aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb')
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBAddress.i16
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBAttachInfo.i4
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBBlock.i2
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBBreakpoint.i15
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBBreakpointLocation.i2
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBBreakpointName.i4
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBBroadcaster.i6
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreter.i8
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreterRunOptions.i14
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBCommandReturnObject.i4
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBCommunication.i3
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBCompileUnit.i36
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBData.i3
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBDebugger.i200
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBEnvironment.i3
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBError.i4
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBEvent.i32
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBExecutionContext.i3
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBFile.i2
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBFileSpec.i2
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBFileSpecList.i3
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBFrame.i64
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBFunction.i2
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBHostOS.i3
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBInstruction.i3
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBInstructionList.i10
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBLanguageRuntime.i3
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBLaunchInfo.i3
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBLineEntry.i38
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBListener.i2
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfoList.i3
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBModule.i31
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBModuleSpec.i3
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBPlatform.i15
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBProcess.i110
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBQueue.i3
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBQueueItem.i3
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBReproducer.i4
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBSection.i22
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBSourceManager.i2
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBStream.i2
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBStringList.i3
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBStructuredData.i9
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBSymbol.i4
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBSymbolContext.i2
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBSymbolContextList.i2
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBTarget.i208
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBThread.i6
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBThreadPlan.i12
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBTrace.i3
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBTraceOptions.i5
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBType.i180
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBTypeEnumMember.i40
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBValue.i72
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBValueList.i111
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBVariablesOptions.i3
-rw-r--r--contrib/llvm-project/lldb/bindings/interface/SBWatchpoint.i2
-rw-r--r--contrib/llvm-project/lldb/bindings/lua/lua-swigsafecast.swig21
-rw-r--r--contrib/llvm-project/lldb/bindings/lua/lua-typemaps.swig104
-rw-r--r--contrib/llvm-project/lldb/bindings/lua/lua-wrapper.swig57
-rw-r--r--contrib/llvm-project/lldb/bindings/lua/lua.swig (renamed from contrib/llvm-project/lldb/bindings/lua.swig)12
-rw-r--r--contrib/llvm-project/lldb/bindings/macros.swig4
-rw-r--r--contrib/llvm-project/lldb/bindings/python/python-extensions.swig27
-rw-r--r--contrib/llvm-project/lldb/bindings/python/python-swigsafecast.swig7
-rw-r--r--contrib/llvm-project/lldb/bindings/python/python-typemaps.h17
-rw-r--r--contrib/llvm-project/lldb/bindings/python/python-typemaps.swig23
-rw-r--r--contrib/llvm-project/lldb/bindings/python/python-wrapper.swig132
-rw-r--r--contrib/llvm-project/lldb/bindings/python/python.swig (renamed from contrib/llvm-project/lldb/bindings/python.swig)50
-rw-r--r--contrib/llvm-project/lldb/docs/_lldb/__init__.py9
-rw-r--r--contrib/llvm-project/lldb/docs/design/overview.rst192
-rw-r--r--contrib/llvm-project/lldb/docs/design/reproducers.rst212
-rw-r--r--contrib/llvm-project/lldb/docs/design/sbapi.rst95
-rw-r--r--contrib/llvm-project/lldb/docs/design/structureddataplugins.md442
-rw-r--r--contrib/llvm-project/lldb/docs/man/lldb-server.rst209
-rw-r--r--contrib/llvm-project/lldb/docs/man/lldb.rst20
-rw-r--r--contrib/llvm-project/lldb/docs/python_api.rst98
-rw-r--r--contrib/llvm-project/lldb/docs/python_api_enums.rst1257
-rw-r--r--contrib/llvm-project/lldb/include/lldb/API/LLDB.h1
-rw-r--r--contrib/llvm-project/lldb/include/lldb/API/SBAddress.h4
-rw-r--r--contrib/llvm-project/lldb/include/lldb/API/SBBreakpoint.h6
-rw-r--r--contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreter.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h4
-rw-r--r--contrib/llvm-project/lldb/include/lldb/API/SBModule.h4
-rw-r--r--contrib/llvm-project/lldb/include/lldb/API/SBPlatform.h5
-rw-r--r--contrib/llvm-project/lldb/include/lldb/API/SBReproducer.h26
-rw-r--r--contrib/llvm-project/lldb/include/lldb/API/SBTarget.h6
-rw-r--r--contrib/llvm-project/lldb/include/lldb/API/SBThreadPlan.h9
-rw-r--r--contrib/llvm-project/lldb/include/lldb/API/SBType.h7
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h20
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocation.h24
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointSite.h13
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointHitCounter.h43
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointLocation.h87
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointSite.h81
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Breakpoint/Watchpoint.h8
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Architecture.h7
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Communication.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Debugger.h6
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h19
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h16
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/IOHandlerCursesGUI.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Module.h4
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h22
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h6
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h36
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h14
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Value.h86
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h6
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h4
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h4
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/DataFormatters/DataVisualization.h6
-rw-r--r--contrib/llvm-project/lldb/include/lldb/DataFormatters/FormatManager.h9
-rw-r--r--contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersContainer.h329
-rw-r--r--contrib/llvm-project/lldb/include/lldb/DataFormatters/StringPrinter.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategory.h48
-rw-r--r--contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategoryMap.h5
-rw-r--r--contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSummary.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSynthetic.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h8
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Expression/ExpressionVariable.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Expression/UtilityFunction.h11
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake6
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Host/Editline.h16
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h22
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Host/Host.h41
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Host/HostInfoBase.h13
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h5
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Host/PseudoTerminal.h47
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h16
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Host/common/NativeRegisterContext.h9
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/CommandCompletions.h59
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h41
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h17
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h9
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h5
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArch.h3
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArray.h3
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueBoolean.h3
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueChar.h3
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h3
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueEnumeration.h3
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h64
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpec.h3
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h3
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormat.h3
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueLanguage.h3
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValuePathMappings.h3
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h7
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueRegex.h3
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueSInt64.h3
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h3
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUInt64.h3
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUUID.h3
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValues.h1
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h7
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h20
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Symbol/CompilerType.h13
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h1
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h24
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Symbol/SymbolContext.h14
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Symbol/SymbolVendor.h8
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Symbol/Type.h26
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h35
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Symbol/UnwindPlan.h1
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h5
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/ABI.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h10
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/InstrumentationRuntime.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/Language.h4
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h18
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h17
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/OperatingSystem.h6
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/Platform.h21
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/PostMortemProcess.h32
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/Process.h172
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/ProcessTrace.h86
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h7
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/Runtime.h33
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/StackFrameRecognizer.h59
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/SystemRuntime.h10
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/Target.h161
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/TargetList.h39
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/Thread.h29
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h384
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanPython.h5
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h19
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInRange.h18
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/ThreadTrace.h61
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/Trace.h203
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/TraceSessionFileParser.h179
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Target/UnwindAssembly.h7
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/ArchSpec.h12
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/Args.h6
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/Broadcaster.h4
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h37
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/Iterable.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/OptionDefinition.h58
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h34
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/RangeMap.h54
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/RegisterValue.h11
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/Reproducer.h265
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h71
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/ReproducerProvider.h434
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/Scalar.h201
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h13
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/StringList.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h8
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/Timer.h8
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/TraceOptions.h21
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/UUID.h17
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/UnimplementedError.h28
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/XcodeSDK.h6
-rw-r--r--contrib/llvm-project/lldb/include/lldb/lldb-defines.h2
-rw-r--r--contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h17
-rw-r--r--contrib/llvm-project/lldb/include/lldb/lldb-forward.h9
-rw-r--r--contrib/llvm-project/lldb/include/lldb/lldb-private-interfaces.h14
-rw-r--r--contrib/llvm-project/lldb/include/lldb/lldb-private-types.h27
-rw-r--r--contrib/llvm-project/lldb/source/API/SBAddress.cpp14
-rw-r--r--contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp30
-rw-r--r--contrib/llvm-project/lldb/source/API/SBBreakpointLocation.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp21
-rw-r--r--contrib/llvm-project/lldb/source/API/SBCommandInterpreterRunOptions.cpp37
-rw-r--r--contrib/llvm-project/lldb/source/API/SBDebugger.cpp46
-rw-r--r--contrib/llvm-project/lldb/source/API/SBError.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/API/SBFrame.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/API/SBFunction.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/API/SBHostOS.cpp9
-rw-r--r--contrib/llvm-project/lldb/source/API/SBInstruction.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/API/SBLineEntry.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/API/SBModule.cpp58
-rw-r--r--contrib/llvm-project/lldb/source/API/SBPlatform.cpp112
-rw-r--r--contrib/llvm-project/lldb/source/API/SBQueueItem.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/API/SBReproducer.cpp97
-rw-r--r--contrib/llvm-project/lldb/source/API/SBReproducerPrivate.h1
-rw-r--r--contrib/llvm-project/lldb/source/API/SBSymbol.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/API/SBTarget.cpp70
-rw-r--r--contrib/llvm-project/lldb/source/API/SBThreadPlan.cpp143
-rw-r--r--contrib/llvm-project/lldb/source/API/SBType.cpp39
-rw-r--r--contrib/llvm-project/lldb/source/API/SBValue.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/API/SystemInitializerFull.cpp23
-rw-r--r--contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp21
-rw-r--r--contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Breakpoint/BreakpointIDList.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp36
-rw-r--r--contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverAddress.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp9
-rw-r--r--contrib/llvm-project/lldb/source/Breakpoint/BreakpointSite.cpp77
-rw-r--r--contrib/llvm-project/lldb/source/Breakpoint/StoppointLocation.cpp32
-rw-r--r--contrib/llvm-project/lldb/source/Breakpoint/StoppointSite.cpp23
-rw-r--r--contrib/llvm-project/lldb/source/Breakpoint/Watchpoint.cpp19
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp202
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp140
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp42
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp206
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp22
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp45
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp145
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp41
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp128
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp99
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp (renamed from contrib/llvm-project/lldb/source/Interpreter/CommandObjectRegexCommand.cpp)14
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.h (renamed from contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h)10
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp216
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectScript.cpp138
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectScript.h (renamed from contrib/llvm-project/lldb/source/Interpreter/CommandObjectScript.h)21
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectSession.cpp208
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectSession.h23
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp17
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp608
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp539
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.cpp158
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.h81
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp305
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.h25
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp109
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp52
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.cpp147
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.h49
-rw-r--r--contrib/llvm-project/lldb/source/Commands/Options.td122
-rw-r--r--contrib/llvm-project/lldb/source/Core/Communication.cpp18
-rw-r--r--contrib/llvm-project/lldb/source/Core/CoreProperties.td4
-rw-r--r--contrib/llvm-project/lldb/source/Core/Debugger.cpp38
-rw-r--r--contrib/llvm-project/lldb/source/Core/Disassembler.cpp92
-rw-r--r--contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Core/IOHandler.cpp27
-rw-r--r--contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp630
-rw-r--r--contrib/llvm-project/lldb/source/Core/Mangled.cpp12
-rw-r--r--contrib/llvm-project/lldb/source/Core/Module.cpp43
-rw-r--r--contrib/llvm-project/lldb/source/Core/ModuleList.cpp39
-rw-r--r--contrib/llvm-project/lldb/source/Core/PluginManager.cpp65
-rw-r--r--contrib/llvm-project/lldb/source/Core/SearchFilter.cpp41
-rw-r--r--contrib/llvm-project/lldb/source/Core/SourceManager.cpp9
-rw-r--r--contrib/llvm-project/lldb/source/Core/Value.cpp53
-rw-r--r--contrib/llvm-project/lldb/source/Core/ValueObject.cpp32
-rw-r--r--contrib/llvm-project/lldb/source/Core/ValueObjectCast.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Core/ValueObjectChild.cpp156
-rw-r--r--contrib/llvm-project/lldb/source/Core/ValueObjectConstResult.cpp21
-rw-r--r--contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Core/ValueObjectMemory.cpp10
-rw-r--r--contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Core/ValueObjectVariable.cpp14
-rw-r--r--contrib/llvm-project/lldb/source/DataFormatters/DataVisualization.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/DataFormatters/TypeCategory.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/DataFormatters/ValueObjectPrinter.cpp47
-rw-r--r--contrib/llvm-project/lldb/source/DataFormatters/VectorType.cpp16
-rw-r--r--contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp118
-rw-r--r--contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp10
-rw-r--r--contrib/llvm-project/lldb/source/Expression/Materializer.cpp34
-rw-r--r--contrib/llvm-project/lldb/source/Expression/REPL.cpp44
-rw-r--r--contrib/llvm-project/lldb/source/Expression/UserExpression.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Host/common/Editline.cpp98
-rw-r--r--contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp24
-rw-r--r--contrib/llvm-project/lldb/source/Host/common/Host.cpp49
-rw-r--r--contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp14
-rw-r--r--contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp33
-rw-r--r--contrib/llvm-project/lldb/source/Host/common/OptionParser.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp21
-rw-r--r--contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp222
-rw-r--r--contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Host/freebsd/Host.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp10
-rw-r--r--contrib/llvm-project/lldb/source/Initialization/SystemInitializerCommon.cpp90
-rw-r--r--contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp400
-rw-r--r--contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp31
-rw-r--r--contrib/llvm-project/lldb/source/Interpreter/CommandObjectScript.cpp68
-rw-r--r--contrib/llvm-project/lldb/source/Interpreter/InterpreterProperties.td4
-rw-r--r--contrib/llvm-project/lldb/source/Interpreter/OptionGroupUUID.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Interpreter/OptionValue.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Interpreter/OptionValueFileColonLine.cpp145
-rw-r--r--contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/Interpreter/OptionValueFormatEntity.cpp5
-rw-r--r--contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp35
-rw-r--r--contrib/llvm-project/lldb/source/Interpreter/Options.cpp20
-rw-r--r--contrib/llvm-project/lldb/source/Interpreter/Property.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp17
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp21
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp17
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp21
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp19
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp35
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp9
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h22
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp99
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h60
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp48
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp30
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h9
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp82
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp19
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h14
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp155
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h20
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h62
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp44
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp20
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp30
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp13
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp24
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp19
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSArray.cpp44
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSError.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSException.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp10
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp14
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp96
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp171
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp50
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp9
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp18
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp197
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h107
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp61
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp92
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h14
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp121
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp143
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp29
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp616
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h111
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp921
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h128
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.cpp29
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h43
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp202
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.h68
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp288
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h86
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp186
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h71
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp289
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.h74
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp656
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h96
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp291
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h83
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp44
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.h66
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp1077
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h220
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp1427
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h279
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h63
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp259
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h76
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp264
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h77
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp262
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h80
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp274
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h84
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp613
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h81
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp186
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h10
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp1211
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h80
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp22
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.cpp25
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.h1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp89
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h18
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h291
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp172
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp143
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp143
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp182
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h31
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp466
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h79
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp276
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h48
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h16
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp131
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h53
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp16
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h27
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp107
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h44
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.cpp58
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h20
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp104
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp179
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h45
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h572
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h25
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h47
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h13
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp144
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h14
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp14
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp10
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp86
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h13
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp386
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h21
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp184
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h71
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp109
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h13
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp108
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp188
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpParser.h3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpTypes.h15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp41
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.h11
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp105
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h21
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp161
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h43
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp339
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h16
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp401
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp15
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp14
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h8
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp70
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h14
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp745
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp12
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h5
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp109
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h1
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h6
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h4
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp73
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h65
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp64
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h146
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp215
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h52
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp114
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h96
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td16
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp97
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h84
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp323
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h170
-rw-r--r--contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Symbol/CompilerType.cpp27
-rw-r--r--contrib/llvm-project/lldb/source/Symbol/DWARFCallFrameInfo.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Symbol/FuncUnwinders.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Symbol/LineTable.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Symbol/LocateSymbolFile.cpp12
-rw-r--r--contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp58
-rw-r--r--contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp258
-rw-r--r--contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp25
-rw-r--r--contrib/llvm-project/lldb/source/Symbol/SymbolVendor.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Symbol/Symtab.cpp26
-rw-r--r--contrib/llvm-project/lldb/source/Symbol/Type.cpp52
-rw-r--r--contrib/llvm-project/lldb/source/Symbol/TypeSystem.cpp110
-rw-r--r--contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp14
-rw-r--r--contrib/llvm-project/lldb/source/Symbol/Variable.cpp5
-rw-r--r--contrib/llvm-project/lldb/source/Target/ABI.cpp16
-rw-r--r--contrib/llvm-project/lldb/source/Target/AssertFrameRecognizer.cpp28
-rw-r--r--contrib/llvm-project/lldb/source/Target/LanguageRuntime.cpp13
-rw-r--r--contrib/llvm-project/lldb/source/Target/MemoryRegionInfo.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Target/OperatingSystem.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Target/Platform.cpp32
-rw-r--r--contrib/llvm-project/lldb/source/Target/Process.cpp281
-rw-r--r--contrib/llvm-project/lldb/source/Target/ProcessTrace.cpp134
-rw-r--r--contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp19
-rw-r--r--contrib/llvm-project/lldb/source/Target/StackFrame.cpp34
-rw-r--r--contrib/llvm-project/lldb/source/Target/StackFrameRecognizer.cpp221
-rw-r--r--contrib/llvm-project/lldb/source/Target/SystemRuntime.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Target/Target.cpp649
-rw-r--r--contrib/llvm-project/lldb/source/Target/TargetList.cpp530
-rw-r--r--contrib/llvm-project/lldb/source/Target/TargetProperties.td20
-rw-r--r--contrib/llvm-project/lldb/source/Target/Thread.cpp32
-rw-r--r--contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp12
-rw-r--r--contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp18
-rw-r--r--contrib/llvm-project/lldb/source/Target/ThreadPlanStepInRange.cpp16
-rw-r--r--contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Target/ThreadPlanStepRange.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Target/ThreadTrace.cpp39
-rw-r--r--contrib/llvm-project/lldb/source/Target/Trace.cpp268
-rw-r--r--contrib/llvm-project/lldb/source/Target/TraceSessionFileParser.cpp223
-rw-r--r--contrib/llvm-project/lldb/source/Target/UnixSignals.cpp86
-rw-r--r--contrib/llvm-project/lldb/source/Target/UnwindAssembly.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp341
-rw-r--r--contrib/llvm-project/lldb/source/Utility/Args.cpp38
-rw-r--r--contrib/llvm-project/lldb/source/Utility/ConstString.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp56
-rw-r--r--contrib/llvm-project/lldb/source/Utility/RegisterValue.cpp32
-rw-r--r--contrib/llvm-project/lldb/source/Utility/Reproducer.cpp199
-rw-r--r--contrib/llvm-project/lldb/source/Utility/ReproducerInstrumentation.cpp31
-rw-r--r--contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp221
-rw-r--r--contrib/llvm-project/lldb/source/Utility/Scalar.cpp1010
-rw-r--r--contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Utility/StringLexer.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Utility/StringList.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Utility/StructuredData.cpp30
-rw-r--r--contrib/llvm-project/lldb/source/Utility/TildeExpressionResolver.cpp7
-rw-r--r--contrib/llvm-project/lldb/source/Utility/Timer.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Utility/TraceOptions.cpp25
-rw-r--r--contrib/llvm-project/lldb/source/Utility/UUID.cpp10
-rw-r--r--contrib/llvm-project/lldb/source/Utility/UnimplementedError.cpp11
-rw-r--r--contrib/llvm-project/lldb/source/Utility/XcodeSDK.cpp6
-rw-r--r--contrib/llvm-project/lldb/source/lldb.cpp7
-rw-r--r--contrib/llvm-project/lldb/tools/driver/Driver.cpp110
-rw-r--r--contrib/llvm-project/lldb/tools/driver/Options.td4
-rw-r--r--contrib/llvm-project/lldb/tools/lldb-server/LLGSOptions.td62
-rw-r--r--contrib/llvm-project/lldb/tools/lldb-server/lldb-gdbserver.cpp297
-rw-r--r--contrib/llvm-project/lldb/tools/lldb-server/lldb-platform.cpp13
684 files changed, 27011 insertions, 17634 deletions
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBAddress.i b/contrib/llvm-project/lldb/bindings/interface/SBAddress.i
index 6fd06c83d293..8e95d36e580d 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBAddress.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBAddress.i
@@ -17,8 +17,9 @@ libraries, bundles, frameworks) being loaded at different
addresses than the addresses found in the object file that
represents them on disk. There are currently two types of addresses
for a section:
- o file addresses
- o load addresses
+
+* file addresses
+* load addresses
File addresses represents the virtual addresses that are in the 'on
disk' object files. These virtual addresses are converted to be
@@ -108,18 +109,17 @@ public:
An address might refer to code or data from an existing module, or it
might refer to something on the stack or heap. The following functions
will only return valid values if the address has been resolved to a code
- or data address using 'void SBAddress::SetLoadAddress(...)' or
- 'lldb::SBAddress SBTarget::ResolveLoadAddress (...)'.") GetSymbolContext;
+ or data address using :py:class:`SBAddress.SetLoadAddress' or
+ :py:class:`SBTarget.ResolveLoadAddress`.") GetSymbolContext;
lldb::SBSymbolContext
GetSymbolContext (uint32_t resolve_scope);
%feature("docstring", "
GetModule() and the following grab individual objects for a given address and
are less efficient if you want more than one symbol related objects.
- Use one of the following when you want multiple debug symbol related
- objects for an address:
- lldb::SBSymbolContext SBAddress::GetSymbolContext (uint32_t resolve_scope);
- lldb::SBSymbolContext SBTarget::ResolveSymbolContextForAddress (const SBAddress &addr, uint32_t resolve_scope);
+ Use :py:class:`SBAddress.GetSymbolContext` or
+ :py:class:`SBTarget.ResolveSymbolContextForAddress` when you want multiple
+ debug symbol related objects for an address.
One or more bits from the SymbolContextItem enumerations can be logically
OR'ed together to more efficiently retrieve multiple symbol objects.") GetModule;
lldb::SBModule
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBAttachInfo.i b/contrib/llvm-project/lldb/bindings/interface/SBAttachInfo.i
index 3f4634e14619..9ac96e6dd7be 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBAttachInfo.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBAttachInfo.i
@@ -7,7 +7,9 @@
//===----------------------------------------------------------------------===//
namespace lldb {
-
+%feature("docstring",
+"Describes how to attach when calling :py:class:`SBTarget.Attach`."
+) SBAttachInfo;
class SBAttachInfo
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBBlock.i b/contrib/llvm-project/lldb/bindings/interface/SBBlock.i
index 812b41fe5c3e..3972b939b18b 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBBlock.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBBlock.i
@@ -22,7 +22,7 @@ public:
~SBBlock ();
%feature("docstring",
- "Does this block represent an inlined function?"
+ "Is this block contained within an inlined function?"
) IsInlined;
bool
IsInlined () const;
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBBreakpoint.i b/contrib/llvm-project/lldb/bindings/interface/SBBreakpoint.i
index a2d747db0bf6..37fcc7fbab48 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBBreakpoint.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBBreakpoint.i
@@ -11,7 +11,7 @@ namespace lldb {
"Represents a logical breakpoint and its associated settings.
For example (from test/functionalities/breakpoint/breakpoint_ignore_count/
-TestBreakpointIgnoreCount.py),
+TestBreakpointIgnoreCount.py),::
def breakpoint_ignore_count_python(self):
'''Use Python APIs to set breakpoint ignore count.'''
@@ -62,13 +62,13 @@ TestBreakpointIgnoreCount.py),
process.Continue()
-SBBreakpoint supports breakpoint location iteration, for example,
+SBBreakpoint supports breakpoint location iteration, for example,::
for bl in breakpoint:
print('breakpoint location load addr: %s' % hex(bl.GetLoadAddress()))
print('breakpoint location condition: %s' % hex(bl.GetCondition()))
-and rich comparison methods which allow the API program to use,
+and rich comparison methods which allow the API program to use,::
if aBreakpoint == bBreakpoint:
...
@@ -100,6 +100,9 @@ public:
void
ClearAllBreakpointSites ();
+ lldb::SBTarget
+ GetTarget() const;
+
lldb::SBBreakpointLocation
FindLocationByAddress (lldb::addr_t vm_addr);
@@ -234,6 +237,8 @@ public:
SBError
AddLocation(SBAddress &address);
+ SBStructuredData SBBreakpoint::SerializeToStructuredData();
+
static bool
EventIsBreakpointEvent (const lldb::SBEvent &event);
@@ -308,6 +313,10 @@ public:
class SBBreakpointListImpl;
+
+%feature("docstring",
+"Represents a list of :py:class:`SBBreakpoint`."
+) SBBreakpointList;
class LLDB_API SBBreakpointList
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBBreakpointLocation.i b/contrib/llvm-project/lldb/bindings/interface/SBBreakpointLocation.i
index dc39c83c2d67..fc37475ba745 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBBreakpointLocation.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBBreakpointLocation.i
@@ -15,7 +15,7 @@ A breakpoint location is defined by the breakpoint that produces it,
and the address that resulted in this particular instantiation.
Each breakpoint location has its settable options.
-SBBreakpoint contains SBBreakpointLocation(s). See docstring of SBBreakpoint
+:py:class:`SBBreakpoint` contains SBBreakpointLocation(s). See docstring of SBBreakpoint
for retrieval of an SBBreakpointLocation from an SBBreakpoint."
) SBBreakpointLocation;
class SBBreakpointLocation
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBBreakpointName.i b/contrib/llvm-project/lldb/bindings/interface/SBBreakpointName.i
index e280d4224591..c0fdcc748988 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBBreakpointName.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBBreakpointName.i
@@ -8,12 +8,12 @@
namespace lldb {
%feature("docstring",
-"Represents a breakpoint name registered in a given SBTarget.
+"Represents a breakpoint name registered in a given :py:class:`SBTarget`.
Breakpoint names provide a way to act on groups of breakpoints. When you add a
name to a group of breakpoints, you can then use the name in all the command
line lldb commands for that name. You can also configure the SBBreakpointName
-options and those options will be propagated to any SBBreakpoints currently
+options and those options will be propagated to any :py:class:`SBBreakpoint` s currently
using that name. Adding a name to a breakpoint will also apply any of the
set options to that breakpoint.
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBBroadcaster.i b/contrib/llvm-project/lldb/bindings/interface/SBBroadcaster.i
index 79100e171b49..e97d8f964bde 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBBroadcaster.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBBroadcaster.i
@@ -9,9 +9,11 @@
namespace lldb {
%feature("docstring",
-"Represents an entity which can broadcast events. A default broadcaster is
+"Represents an entity which can broadcast events.
+
+A default broadcaster is
associated with an SBCommandInterpreter, SBProcess, and SBTarget. For
-example, use
+example, use ::
broadcaster = process.GetBroadcaster()
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreter.i b/contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreter.i
index 498084ae3ab1..b9a32716cfd6 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreter.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreter.i
@@ -9,9 +9,11 @@
namespace lldb {
%feature("docstring",
-"SBCommandInterpreter handles/interprets commands for lldb. You get the
-command interpreter from the SBDebugger instance. For example (from test/
-python_api/interpreter/TestCommandInterpreterAPI.py),
+"SBCommandInterpreter handles/interprets commands for lldb.
+
+You get the command interpreter from the :py:class:`SBDebugger` instance.
+
+For example (from test/ python_api/interpreter/TestCommandInterpreterAPI.py),::
def command_interpreter_api(self):
'''Test the SBCommandInterpreter APIs.'''
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreterRunOptions.i b/contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreterRunOptions.i
index f9ccbbd24dbe..1a618a228bbe 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreterRunOptions.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBCommandInterpreterRunOptions.i
@@ -10,13 +10,15 @@ namespace lldb {
%feature("docstring",
"SBCommandInterpreterRunOptions controls how the RunCommandInterpreter runs the code it is fed.
+
A default SBCommandInterpreterRunOptions object has:
- StopOnContinue: false
- StopOnError: false
- StopOnCrash: false
- EchoCommands: true
- PrintResults: true
- AddToHistory: true
+
+* StopOnContinue: false
+* StopOnError: false
+* StopOnCrash: false
+* EchoCommands: true
+* PrintResults: true
+* AddToHistory: true
") SBCommandInterpreterRunOptions;
class SBCommandInterpreterRunOptions
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBCommandReturnObject.i b/contrib/llvm-project/lldb/bindings/interface/SBCommandReturnObject.i
index affa16520f28..b07ef1c5eb1c 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBCommandReturnObject.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBCommandReturnObject.i
@@ -10,10 +10,10 @@ namespace lldb {
%feature("docstring",
"Represents a container which holds the result from command execution.
-It works with SBCommandInterpreter.HandleCommand() to encapsulate the result
+It works with :py:class:`SBCommandInterpreter.HandleCommand()` to encapsulate the result
of command execution.
-See SBCommandInterpreter for example usage of SBCommandReturnObject."
+See :py:class:`SBCommandInterpreter` for example usage of SBCommandReturnObject."
) SBCommandReturnObject;
class SBCommandReturnObject
{
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBCommunication.i b/contrib/llvm-project/lldb/bindings/interface/SBCommunication.i
index 87d3d0c9c5e4..8611e83e92ad 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBCommunication.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBCommunication.i
@@ -8,6 +8,9 @@
namespace lldb {
+%feature("docstring",
+"Allows sending/receiving data."
+) SBCommunication;
class SBCommunication
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBCompileUnit.i b/contrib/llvm-project/lldb/bindings/interface/SBCompileUnit.i
index d6a4c07038c6..4c8efaedb7dc 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBCompileUnit.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBCompileUnit.i
@@ -11,7 +11,7 @@ namespace lldb {
%feature("docstring",
"Represents a compilation unit, or compiled source file.
-SBCompileUnit supports line entry iteration. For example,
+SBCompileUnit supports line entry iteration. For example,::
# Now get the SBSymbolContext from this frame. We want everything. :-)
context = frame0.GetSymbolContext(lldb.eSymbolContextEverything)
@@ -25,23 +25,23 @@ SBCompileUnit supports line entry iteration. For example,
print('start addr: %s' % str(lineEntry.GetStartAddress()))
print('end addr: %s' % str(lineEntry.GetEndAddress()))
-produces:
-
-line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:20
-start addr: a.out[0x100000d98]
-end addr: a.out[0x100000da3]
-line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:21
-start addr: a.out[0x100000da3]
-end addr: a.out[0x100000da9]
-line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:22
-start addr: a.out[0x100000da9]
-end addr: a.out[0x100000db6]
-line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:23
-start addr: a.out[0x100000db6]
-end addr: a.out[0x100000dbc]
-...
-
-See also SBSymbolContext and SBLineEntry"
+produces: ::
+
+ line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:20
+ start addr: a.out[0x100000d98]
+ end addr: a.out[0x100000da3]
+ line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:21
+ start addr: a.out[0x100000da3]
+ end addr: a.out[0x100000da9]
+ line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:22
+ start addr: a.out[0x100000da9]
+ end addr: a.out[0x100000db6]
+ line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:23
+ start addr: a.out[0x100000db6]
+ end addr: a.out[0x100000dbc]
+ ...
+
+See also :py:class:`SBSymbolContext` and :py:class:`SBLineEntry`"
) SBCompileUnit;
class SBCompileUnit
{
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBData.i b/contrib/llvm-project/lldb/bindings/interface/SBData.i
index 3e74240329e0..a1fb4472cd23 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBData.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBData.i
@@ -9,6 +9,9 @@
namespace lldb {
+%feature("docstring",
+"Represents a data buffer."
+) SBData;
class SBData
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBDebugger.i b/contrib/llvm-project/lldb/bindings/interface/SBDebugger.i
index f2e23a7ed780..cf4411980cc3 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBDebugger.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBDebugger.i
@@ -12,108 +12,108 @@ namespace lldb {
"SBDebugger is the primordial object that creates SBTargets and provides
access to them. It also manages the overall debugging experiences.
-For example (from example/disasm.py),
-
-import lldb
-import os
-import sys
-
-def disassemble_instructions (insts):
- for i in insts:
- print i
-
-...
-
-# Create a new debugger instance
-debugger = lldb.SBDebugger.Create()
-
-# When we step or continue, don't return from the function until the process
-# stops. We do this by setting the async mode to false.
-debugger.SetAsync (False)
-
-# Create a target from a file and arch
-print('Creating a target for \'%s\'' % exe)
-
-target = debugger.CreateTargetWithFileAndArch (exe, lldb.LLDB_ARCH_DEFAULT)
-
-if target:
- # If the target is valid set a breakpoint at main
- main_bp = target.BreakpointCreateByName (fname, target.GetExecutable().GetFilename());
-
- print main_bp
-
- # Launch the process. Since we specified synchronous mode, we won't return
- # from this function until we hit the breakpoint at main
- process = target.LaunchSimple (None, None, os.getcwd())
-
- # Make sure the launch went ok
- if process:
- # Print some simple process info
- state = process.GetState ()
- print process
- if state == lldb.eStateStopped:
- # Get the first thread
- thread = process.GetThreadAtIndex (0)
- if thread:
- # Print some simple thread info
- print thread
- # Get the first frame
- frame = thread.GetFrameAtIndex (0)
- if frame:
- # Print some simple frame info
- print frame
- function = frame.GetFunction()
- # See if we have debug info (a function)
- if function:
- # We do have a function, print some info for the function
- print function
- # Now get all instructions for this function and print them
- insts = function.GetInstructions(target)
- disassemble_instructions (insts)
- else:
- # See if we have a symbol in the symbol table for where we stopped
- symbol = frame.GetSymbol();
- if symbol:
- # We do have a symbol, print some info for the symbol
- print symbol
- # Now get all instructions for this symbol and print them
- insts = symbol.GetInstructions(target)
+For example (from example/disasm.py),::
+
+ import lldb
+ import os
+ import sys
+
+ def disassemble_instructions (insts):
+ for i in insts:
+ print i
+
+ ...
+
+ # Create a new debugger instance
+ debugger = lldb.SBDebugger.Create()
+
+ # When we step or continue, don't return from the function until the process
+ # stops. We do this by setting the async mode to false.
+ debugger.SetAsync (False)
+
+ # Create a target from a file and arch
+ print('Creating a target for \'%s\'' % exe)
+
+ target = debugger.CreateTargetWithFileAndArch (exe, lldb.LLDB_ARCH_DEFAULT)
+
+ if target:
+ # If the target is valid set a breakpoint at main
+ main_bp = target.BreakpointCreateByName (fname, target.GetExecutable().GetFilename());
+
+ print main_bp
+
+ # Launch the process. Since we specified synchronous mode, we won't return
+ # from this function until we hit the breakpoint at main
+ process = target.LaunchSimple (None, None, os.getcwd())
+
+ # Make sure the launch went ok
+ if process:
+ # Print some simple process info
+ state = process.GetState ()
+ print process
+ if state == lldb.eStateStopped:
+ # Get the first thread
+ thread = process.GetThreadAtIndex (0)
+ if thread:
+ # Print some simple thread info
+ print thread
+ # Get the first frame
+ frame = thread.GetFrameAtIndex (0)
+ if frame:
+ # Print some simple frame info
+ print frame
+ function = frame.GetFunction()
+ # See if we have debug info (a function)
+ if function:
+ # We do have a function, print some info for the function
+ print function
+ # Now get all instructions for this function and print them
+ insts = function.GetInstructions(target)
disassemble_instructions (insts)
-
- registerList = frame.GetRegisters()
- print('Frame registers (size of register set = %d):' % registerList.GetSize())
- for value in registerList:
- #print value
- print('%s (number of children = %d):' % (value.GetName(), value.GetNumChildren()))
- for child in value:
- print('Name: ', child.GetName(), ' Value: ', child.GetValue())
-
- print('Hit the breakpoint at main, enter to continue and wait for program to exit or \'Ctrl-D\'/\'quit\' to terminate the program')
- next = sys.stdin.readline()
- if not next or next.rstrip('\n') == 'quit':
- print('Terminating the inferior process...')
- process.Kill()
+ else:
+ # See if we have a symbol in the symbol table for where we stopped
+ symbol = frame.GetSymbol();
+ if symbol:
+ # We do have a symbol, print some info for the symbol
+ print symbol
+ # Now get all instructions for this symbol and print them
+ insts = symbol.GetInstructions(target)
+ disassemble_instructions (insts)
+
+ registerList = frame.GetRegisters()
+ print('Frame registers (size of register set = %d):' % registerList.GetSize())
+ for value in registerList:
+ #print value
+ print('%s (number of children = %d):' % (value.GetName(), value.GetNumChildren()))
+ for child in value:
+ print('Name: ', child.GetName(), ' Value: ', child.GetValue())
+
+ print('Hit the breakpoint at main, enter to continue and wait for program to exit or \'Ctrl-D\'/\'quit\' to terminate the program')
+ next = sys.stdin.readline()
+ if not next or next.rstrip('\\n') == 'quit':
+ print('Terminating the inferior process...')
+ process.Kill()
+ else:
+ # Now continue to the program exit
+ process.Continue()
+ # When we return from the above function we will hopefully be at the
+ # program exit. Print out some process info
+ print process
+ elif state == lldb.eStateExited:
+ print('Didn\'t hit the breakpoint at main, program has exited...')
else:
- # Now continue to the program exit
- process.Continue()
- # When we return from the above function we will hopefully be at the
- # program exit. Print out some process info
- print process
- elif state == lldb.eStateExited:
- print('Didn\'t hit the breakpoint at main, program has exited...')
- else:
- print('Unexpected process state: %s, killing process...' % debugger.StateAsCString (state))
- process.Kill()
+ 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:
+to do this is: ::
-target = debugger.CreateTarget('')
-error = lldb.SBError()
-process = target.AttachToProcessWithName(debugger.GetListener(), 'PROCESS_NAME', False, error)
+ target = debugger.CreateTarget('')
+ error = lldb.SBError()
+ process = target.AttachToProcessWithName(debugger.GetListener(), 'PROCESS_NAME', False, error)
-or the equivalent arguments for AttachToProcessWithID.") SBDebugger;
+or the equivalent arguments for :py:class:`SBTarget.AttachToProcessWithID` .") SBDebugger;
class SBDebugger
{
public:
@@ -498,12 +498,12 @@ A tuple with the number of errors encountered by the interpreter, a boolean
indicating whether quitting the interpreter was requested and another boolean
set to True in case of a crash.
-Example:
+Example: ::
-# Start an interactive lldb session from a script (with a valid debugger object
-# created beforehand):
-n_errors, quit_requested, has_crashed = debugger.RunCommandInterpreter(True,
- False, lldb.SBCommandInterpreterRunOptions(), 0, False, False)") RunCommandInterpreter;
+ # Start an interactive lldb session from a script (with a valid debugger object
+ # created beforehand):
+ n_errors, quit_requested, has_crashed = debugger.RunCommandInterpreter(True,
+ False, lldb.SBCommandInterpreterRunOptions(), 0, False, False)") RunCommandInterpreter;
%apply int& INOUT { int& num_errors };
%apply bool& INOUT { bool& quit_requested };
%apply bool& INOUT { bool& stopped_for_crash };
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBEnvironment.i b/contrib/llvm-project/lldb/bindings/interface/SBEnvironment.i
index 4ca22fc314d2..daf25bc26d9c 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBEnvironment.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBEnvironment.i
@@ -11,7 +11,8 @@ namespace lldb {
%feature("docstring",
"Represents the environment of a certain process.
-Example:
+Example: ::
+
for entry in lldb.debugger.GetSelectedTarget().GetEnvironment().GetEntries():
print(entry)
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBError.i b/contrib/llvm-project/lldb/bindings/interface/SBError.i
index ea48e2263a77..5af6b4856bd8 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBError.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBError.i
@@ -11,7 +11,7 @@ namespace lldb {
%feature("docstring",
"Represents a container for holding any error code.
-For example (from test/python_api/hello_world/TestHelloWorld.py),
+For example (from test/python_api/hello_world/TestHelloWorld.py), ::
def hello_world_attach_with_id_api(self):
'''Create target, spawn a process, and attach to it by id.'''
@@ -45,7 +45,7 @@ For example (from test/python_api/hello_world/TestHelloWorld.py),
checks that after the attach, there is no error condition by asserting
that error.Success() is True and we get back a valid process object.
-And (from test/python_api/event/TestEvent.py),
+And (from test/python_api/event/TestEvent.py), ::
# Now launch the process, and do not stop at entry point.
error = lldb.SBError()
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBEvent.i b/contrib/llvm-project/lldb/bindings/interface/SBEvent.i
index 99aa5319e371..2ebf599eb893 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBEvent.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBEvent.i
@@ -13,27 +13,27 @@ class SBBroadcaster;
%feature("docstring",
"API clients can register to receive events.
-For example, check out the following output:
+For example, check out the following output: ::
-Try wait for event...
-Event description: 0x103d0bb70 Event: broadcaster = 0x1009c8410, type = 0x00000001, data = { process = 0x1009c8400 (pid = 21528), state = running}
-Event data flavor: Process::ProcessEventData
-Process state: running
+ Try wait for event...
+ Event description: 0x103d0bb70 Event: broadcaster = 0x1009c8410, type = 0x00000001, data = { process = 0x1009c8400 (pid = 21528), state = running}
+ Event data flavor: Process::ProcessEventData
+ Process state: running
-Try wait for event...
-Event description: 0x103a700a0 Event: broadcaster = 0x1009c8410, type = 0x00000001, data = { process = 0x1009c8400 (pid = 21528), state = stopped}
-Event data flavor: Process::ProcessEventData
-Process state: stopped
+ Try wait for event...
+ Event description: 0x103a700a0 Event: broadcaster = 0x1009c8410, type = 0x00000001, data = { process = 0x1009c8400 (pid = 21528), state = stopped}
+ Event data flavor: Process::ProcessEventData
+ Process state: stopped
-Try wait for event...
-Event description: 0x103d0d4a0 Event: broadcaster = 0x1009c8410, type = 0x00000001, data = { process = 0x1009c8400 (pid = 21528), state = exited}
-Event data flavor: Process::ProcessEventData
-Process state: exited
+ Try wait for event...
+ Event description: 0x103d0d4a0 Event: broadcaster = 0x1009c8410, type = 0x00000001, data = { process = 0x1009c8400 (pid = 21528), state = exited}
+ Event data flavor: Process::ProcessEventData
+ Process state: exited
-Try wait for event...
-timeout occurred waiting for event...
+ Try wait for event...
+ timeout occurred waiting for event...
-from test/python_api/event/TestEventspy:
+from test/python_api/event/TestEventspy: ::
def do_listen_for_and_print_event(self):
'''Create a listener and use SBEvent API to print the events received.'''
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBExecutionContext.i b/contrib/llvm-project/lldb/bindings/interface/SBExecutionContext.i
index 46968d04ae32..5fc5c0571182 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBExecutionContext.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBExecutionContext.i
@@ -8,6 +8,9 @@
namespace lldb {
+%feature("docstring",
+"Describes the program context in which a command should be executed."
+) SBExecutionContext;
class SBExecutionContext
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBFile.i b/contrib/llvm-project/lldb/bindings/interface/SBFile.i
index c86c5f26f147..4a2f58e0e78f 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBFile.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBFile.i
@@ -93,7 +93,7 @@ public:
If there is no underlying python file to unwrap, GetFile will
use the file descriptor, if available to create a new python
- file object using `open(fd, mode=..., closefd=False)`
+ file object using ``open(fd, mode=..., closefd=False)``
");
FileSP GetFile();
};
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBFileSpec.i b/contrib/llvm-project/lldb/bindings/interface/SBFileSpec.i
index d287a940c051..b549321487ec 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBFileSpec.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBFileSpec.i
@@ -13,7 +13,7 @@ namespace lldb {
basename. The string values of the paths are put into uniqued string pools
for fast comparisons and efficient memory usage.
-For example, the following code
+For example, the following code ::
lineEntry = context.GetLineEntry()
self.expect(lineEntry.GetFileSpec().GetDirectory(), 'The line entry should have the correct directory',
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBFileSpecList.i b/contrib/llvm-project/lldb/bindings/interface/SBFileSpecList.i
index 96641613f459..384dd4c4ae08 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBFileSpecList.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBFileSpecList.i
@@ -8,6 +8,9 @@
namespace lldb {
+%feature("docstring",
+"Represents a list of :py:class:`SBFileSpec`."
+) SBFileSpecList;
class SBFileSpecList
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBFrame.i b/contrib/llvm-project/lldb/bindings/interface/SBFrame.i
index c65b88f863e7..7bbf63c713f3 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBFrame.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBFrame.i
@@ -10,34 +10,35 @@ namespace lldb {
%feature("docstring",
"Represents one of the stack frames associated with a thread.
-SBThread contains SBFrame(s). For example (from test/lldbutil.py),
-def print_stacktrace(thread, string_buffer = False):
- '''Prints a simple stack trace of this thread.'''
+SBThread contains SBFrame(s). For example (from test/lldbutil.py), ::
- ...
+ def print_stacktrace(thread, string_buffer = False):
+ '''Prints a simple stack trace of this thread.'''
- for i in range(depth):
- frame = thread.GetFrameAtIndex(i)
- function = frame.GetFunction()
+ ...
- load_addr = addrs[i].GetLoadAddress(target)
- if not function:
- file_addr = addrs[i].GetFileAddress()
- start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress()
- symbol_offset = file_addr - start_addr
- print >> output, ' frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}'.format(
- num=i, addr=load_addr, mod=mods[i], symbol=symbols[i], offset=symbol_offset)
- else:
- print >> output, ' frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}'.format(
- num=i, addr=load_addr, mod=mods[i],
- func='%s [inlined]' % funcs[i] if frame.IsInlined() else funcs[i],
- file=files[i], line=lines[i],
- args=get_args_as_string(frame, showFuncName=False) if not frame.IsInlined() else '()')
+ for i in range(depth):
+ frame = thread.GetFrameAtIndex(i)
+ function = frame.GetFunction()
- ...
+ load_addr = addrs[i].GetLoadAddress(target)
+ if not function:
+ file_addr = addrs[i].GetFileAddress()
+ start_addr = frame.GetSymbol().GetStartAddress().GetFileAddress()
+ symbol_offset = file_addr - start_addr
+ print >> output, ' frame #{num}: {addr:#016x} {mod}`{symbol} + {offset}'.format(
+ num=i, addr=load_addr, mod=mods[i], symbol=symbols[i], offset=symbol_offset)
+ else:
+ print >> output, ' frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}'.format(
+ num=i, addr=load_addr, mod=mods[i],
+ func='%s [inlined]' % funcs[i] if frame.IsInlined() else funcs[i],
+ file=files[i], line=lines[i],
+ args=get_args_as_string(frame, showFuncName=False) if not frame.IsInlined() else '()')
+
+ ...
-And,
+And, ::
for frame in thread:
print frame
@@ -246,20 +247,27 @@ public:
%feature("docstring", "
Get a lldb.SBValue for a variable path.
- Variable paths can include access to pointer or instance members:
+ Variable paths can include access to pointer or instance members: ::
+
rect_ptr->origin.y
pt.x
- Pointer dereferences:
+
+ Pointer dereferences: ::
+
*this->foo_ptr
**argv
- Address of:
+
+ Address of: ::
+
&pt
&my_array[3].x
- Array accesses and treating pointers as arrays:
+
+ Array accesses and treating pointers as arrays: ::
+
int_array[1]
pt_ptr[22].x
- Unlike EvaluateExpression() which returns lldb.SBValue objects
+ Unlike `EvaluateExpression()` which returns :py:class:`SBValue` objects
with constant copies of the values at the time of evaluation,
the result of this function is a value that will continue to
track the current value of the value as execution progresses
@@ -274,7 +282,7 @@ public:
Find variables, register sets, registers, or persistent variables using
the frame as the scope.
- The version that doesn't supply a 'use_dynamic' value will use the
+ The version that doesn't supply a ``use_dynamic`` value will use the
target's default.") FindValue;
lldb::SBValue
FindValue (const char *name, ValueType value_type);
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBFunction.i b/contrib/llvm-project/lldb/bindings/interface/SBFunction.i
index 630c4db22c55..dec073e9e12f 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBFunction.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBFunction.i
@@ -11,7 +11,7 @@ namespace lldb {
%feature("docstring",
"Represents a generic function, which can be inlined or not.
-For example (from test/lldbutil.py, but slightly modified for doc purpose),
+For example (from test/lldbutil.py, but slightly modified for doc purpose),::
...
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBHostOS.i b/contrib/llvm-project/lldb/bindings/interface/SBHostOS.i
index 14f4186cb9f3..791fa5a2085e 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBHostOS.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBHostOS.i
@@ -8,6 +8,9 @@
namespace lldb {
+%feature("docstring",
+"Provides information about the host system."
+) SBHostOS;
class SBHostOS
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBInstruction.i b/contrib/llvm-project/lldb/bindings/interface/SBInstruction.i
index d50a080fd045..e9e018b7deed 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBInstruction.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBInstruction.i
@@ -13,6 +13,9 @@
namespace lldb {
+%feature("docstring",
+"Represents a (machine language) instruction."
+) SBInstruction;
class SBInstruction
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBInstructionList.i b/contrib/llvm-project/lldb/bindings/interface/SBInstructionList.i
index 135732302757..b51c0374c3ad 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBInstructionList.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBInstructionList.i
@@ -14,12 +14,12 @@ namespace lldb {
"Represents a list of machine instructions. SBFunction and SBSymbol have
GetInstructions() methods which return SBInstructionList instances.
-SBInstructionList supports instruction (SBInstruction instance) iteration.
-For example (see also SBDebugger for a more complete example),
+SBInstructionList supports instruction (:py:class:`SBInstruction` instance) iteration.
+For example (see also :py:class:`SBDebugger` for a more complete example), ::
-def disassemble_instructions (insts):
- for i in insts:
- print i
+ def disassemble_instructions (insts):
+ for i in insts:
+ print i
defines a function which takes an SBInstructionList instance and prints out
the machine instructions in assembly format."
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBLanguageRuntime.i b/contrib/llvm-project/lldb/bindings/interface/SBLanguageRuntime.i
index f28170b9ce77..d8698ee36c0d 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBLanguageRuntime.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBLanguageRuntime.i
@@ -8,6 +8,9 @@
namespace lldb {
+%feature("docstring",
+"Utility functions for :ref:`LanguageType`"
+) SBLanguageRuntime;
class SBLanguageRuntime
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBLaunchInfo.i b/contrib/llvm-project/lldb/bindings/interface/SBLaunchInfo.i
index 1de89b58b272..d76656ddd493 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBLaunchInfo.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBLaunchInfo.i
@@ -8,6 +8,9 @@
namespace lldb {
+%feature("docstring",
+"Describes how a target or program should be launched."
+) SBLaunchInfo;
class SBLaunchInfo
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBLineEntry.i b/contrib/llvm-project/lldb/bindings/interface/SBLineEntry.i
index be365377ba8b..24f25ed1b4e5 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBLineEntry.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBLineEntry.i
@@ -10,7 +10,9 @@ namespace lldb {
%feature("docstring",
"Specifies an association with a contiguous range of instructions and
-a source file location. SBCompileUnit contains SBLineEntry(s). For example,
+a source file location.
+
+:py:class:`SBCompileUnit` contains SBLineEntry(s). For example, ::
for lineEntry in compileUnit:
print('line entry: %s:%d' % (str(lineEntry.GetFileSpec()),
@@ -18,23 +20,23 @@ a source file location. SBCompileUnit contains SBLineEntry(s). For example,
print('start addr: %s' % str(lineEntry.GetStartAddress()))
print('end addr: %s' % str(lineEntry.GetEndAddress()))
-produces:
-
-line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:20
-start addr: a.out[0x100000d98]
-end addr: a.out[0x100000da3]
-line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:21
-start addr: a.out[0x100000da3]
-end addr: a.out[0x100000da9]
-line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:22
-start addr: a.out[0x100000da9]
-end addr: a.out[0x100000db6]
-line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:23
-start addr: a.out[0x100000db6]
-end addr: a.out[0x100000dbc]
-...
-
-See also SBCompileUnit."
+produces: ::
+
+ line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:20
+ start addr: a.out[0x100000d98]
+ end addr: a.out[0x100000da3]
+ line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:21
+ start addr: a.out[0x100000da3]
+ end addr: a.out[0x100000da9]
+ line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:22
+ start addr: a.out[0x100000da9]
+ end addr: a.out[0x100000db6]
+ line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:23
+ start addr: a.out[0x100000db6]
+ end addr: a.out[0x100000dbc]
+ ...
+
+See also :py:class:`SBCompileUnit` ."
) SBLineEntry;
class SBLineEntry
{
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBListener.i b/contrib/llvm-project/lldb/bindings/interface/SBListener.i
index 535aef9f0ae7..9062e7534423 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBListener.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBListener.i
@@ -11,7 +11,7 @@ namespace lldb {
%feature("docstring",
"API clients can register its own listener to debugger events.
-See aslo SBEvent for example usage of creating and adding a listener."
+See also :py:class:`SBEvent` for example usage of creating and adding a listener."
) SBListener;
class SBListener
{
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfoList.i b/contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfoList.i
index e408fc0f88b8..c2e74f1cd0dc 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfoList.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfoList.i
@@ -8,6 +8,9 @@
namespace lldb {
+%feature("docstring",
+"Represents a list of :py:class:`SBMemoryRegionInfo`."
+) SBMemoryRegionInfoList;
class SBMemoryRegionInfoList
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBModule.i b/contrib/llvm-project/lldb/bindings/interface/SBModule.i
index e902af0c49ce..606c9a5bbd0c 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBModule.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBModule.i
@@ -40,30 +40,30 @@ The module is designed to be able to select a single slice of an
executable image as it would appear on disk and during program
execution.
-You can retrieve SBModule from SBSymbolContext, which in turn is available
+You can retrieve SBModule from :py:class:`SBSymbolContext` , which in turn is available
from SBFrame.
-SBModule supports symbol iteration, for example,
+SBModule supports symbol iteration, for example, ::
for symbol in module:
name = symbol.GetName()
saddr = symbol.GetStartAddress()
eaddr = symbol.GetEndAddress()
-and rich comparison methods which allow the API program to use,
+and rich comparison methods which allow the API program to use, ::
if thisModule == thatModule:
print('This module is the same as that module')
to test module equality. A module also contains object file sections, namely
-SBSection. SBModule supports section iteration through section_iter(), for
-example,
+:py:class:`SBSection` . SBModule supports section iteration through section_iter(), for
+example, ::
print('Number of sections: %d' % module.GetNumSections())
for sec in module.section_iter():
print(sec)
-And to iterate the symbols within a SBSection, use symbol_in_section_iter(),
+And to iterate the symbols within a SBSection, use symbol_in_section_iter(), ::
# Iterates the text section and prints each symbols within each sub-section.
for subsec in text_sec:
@@ -72,7 +72,7 @@ And to iterate the symbols within a SBSection, use symbol_in_section_iter(),
print(INDENT2 + repr(sym))
print(INDENT2 + 'symbol type: %s' % symbol_type_to_str(sym.GetType()))
-produces this following output:
+produces this following output: ::
[0x0000000100001780-0x0000000100001d5c) a.out.__TEXT.__text
id = {0x00000004}, name = 'mask_access(MaskAction, unsigned int)', range = [0x00000001000017c0-0x0000000100001870)
@@ -204,15 +204,15 @@ public:
GetCompileUnitAtIndex (uint32_t);
%feature("docstring", "
- Find compile units related to *this module and passed source
+ Find compile units related to this module and passed source
file.
@param[in] sb_file_spec
- A lldb::SBFileSpec object that contains source file
+ A :py:class:`SBFileSpec` object that contains source file
specification.
@return
- A lldb::SBSymbolContextList that gets filled in with all of
+ A :py:class:`SBSymbolContextList` that gets filled in with all of
the symbol contexts for all the matches.") FindCompileUnits;
lldb::SBSymbolContextList
FindCompileUnits (const lldb::SBFileSpec &sb_file_spec);
@@ -353,6 +353,17 @@ public:
static uint32_t
GetNumberAllocatedModules();
+ %feature("docstring", "
+ Removes all modules which are no longer needed by any part of LLDB from
+ the module cache.
+
+ This is an implementation detail exposed for testing and should not be
+ relied upon. Use SBDebugger::MemoryPressureDetected instead to reduce
+ LLDB's memory consumption during execution.
+ ") GarbageCollectAllocatedModules;
+ static void
+ GarbageCollectAllocatedModules();
+
STRING_EXTENSION(SBModule)
#ifdef SWIGPYTHON
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBModuleSpec.i b/contrib/llvm-project/lldb/bindings/interface/SBModuleSpec.i
index 64d0aa641a77..8b4c6a92160a 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBModuleSpec.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBModuleSpec.i
@@ -95,6 +95,9 @@ public:
};
+%feature("docstring",
+"Represents a list of :py:class:`SBModuleSpec`."
+) SBModuleSpecList;
class SBModuleSpecList
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBPlatform.i b/contrib/llvm-project/lldb/bindings/interface/SBPlatform.i
index 81945222c059..65615be7a361 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBPlatform.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBPlatform.i
@@ -9,6 +9,9 @@
namespace lldb {
+%feature("docstring",
+"Describes how :py:class:`SBPlatform.ConnectRemote` connects to a remote platform."
+) SBPlatformConnectOptions;
class SBPlatformConnectOptions
{
public:
@@ -42,9 +45,13 @@ public:
SetLocalCacheDirectory(const char *path);
};
+%feature("docstring",
+"Represents a shell command that can be run by :py:class:`SBPlatform.Run`."
+) SBPlatformShellCommand;
class SBPlatformShellCommand
{
public:
+ SBPlatformShellCommand (const char *shell, const char *shell_command);
SBPlatformShellCommand (const char *shell_command);
SBPlatformShellCommand (const SBPlatformShellCommand &rhs);
@@ -55,6 +62,12 @@ public:
Clear();
const char *
+ GetShell();
+
+ void
+ SetShell(const char *shell_interpreter);
+
+ const char *
GetCommand();
void
@@ -97,7 +110,7 @@ current processes on the remote host, attach to one of those processes,
install programs on the remote system, attach and launch processes,
and much more.
-Every SBTarget has a corresponding SBPlatform. The platform can be
+Every :py:class:`SBTarget` has a corresponding SBPlatform. The platform can be
specified upon target creation, or the currently selected platform
will attempt to be used when creating the target automatically as long
as the currently selected platform matches the target architecture
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBProcess.i b/contrib/llvm-project/lldb/bindings/interface/SBProcess.i
index b54c4629f9df..e30b89d1ed39 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBProcess.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBProcess.i
@@ -11,24 +11,22 @@ namespace lldb {
%feature("docstring",
"Represents the process associated with the target program.
-SBProcess supports thread iteration. For example (from test/lldbutil.py),
-
-# ==================================================
-# Utility functions related to Threads and Processes
-# ==================================================
-
-def get_stopped_threads(process, reason):
- '''Returns the thread(s) with the specified stop reason in a list.
-
- The list can be empty if no such thread exists.
- '''
- threads = []
- for t in process:
- if t.GetStopReason() == reason:
- threads.append(t)
- return threads
-
-...
+SBProcess supports thread iteration. For example (from test/lldbutil.py), ::
+
+ # ==================================================
+ # Utility functions related to Threads and Processes
+ # ==================================================
+
+ def get_stopped_threads(process, reason):
+ '''Returns the thread(s) with the specified stop reason in a list.
+
+ The list can be empty if no such thread exists.
+ '''
+ threads = []
+ for t in process:
+ if t.GetStopReason() == reason:
+ threads.append(t)
+ return threads
"
) SBProcess;
class SBProcess
@@ -246,67 +244,67 @@ public:
%feature("autodoc", "
Reads memory from the current process's address space and removes any
traps that may have been inserted into the memory. It returns the byte
- buffer in a Python string. Example:
+ buffer in a Python string. Example: ::
- # Read 4 bytes from address 'addr' and assume error.Success() is True.
- content = process.ReadMemory(addr, 4, error)
- new_bytes = bytearray(content)") ReadMemory;
+ # Read 4 bytes from address 'addr' and assume error.Success() is True.
+ content = process.ReadMemory(addr, 4, error)
+ new_bytes = bytearray(content)") ReadMemory;
size_t
ReadMemory (addr_t addr, void *buf, size_t size, lldb::SBError &error);
%feature("autodoc", "
Writes memory to the current process's address space and maintains any
- traps that might be present due to software breakpoints. Example:
+ traps that might be present due to software breakpoints. Example: ::
- # Create a Python string from the byte array.
- new_value = str(bytes)
- result = process.WriteMemory(addr, new_value, error)
- if not error.Success() or result != len(bytes):
- print('SBProcess.WriteMemory() failed!')") WriteMemory;
+ # Create a Python string from the byte array.
+ new_value = str(bytes)
+ result = process.WriteMemory(addr, new_value, error)
+ if not error.Success() or result != len(bytes):
+ print('SBProcess.WriteMemory() failed!')") WriteMemory;
size_t
WriteMemory (addr_t addr, const void *buf, size_t size, lldb::SBError &error);
%feature("autodoc", "
Reads a NULL terminated C string from the current process's address space.
It returns a python string of the exact length, or truncates the string if
- the maximum character limit is reached. Example:
+ the maximum character limit is reached. Example: ::
- # Read a C string of at most 256 bytes from address '0x1000'
- error = lldb.SBError()
- cstring = process.ReadCStringFromMemory(0x1000, 256, error)
- if error.Success():
- print('cstring: ', cstring)
- else
- print('error: ', error)") ReadCStringFromMemory;
+ # Read a C string of at most 256 bytes from address '0x1000'
+ error = lldb.SBError()
+ cstring = process.ReadCStringFromMemory(0x1000, 256, error)
+ if error.Success():
+ print('cstring: ', cstring)
+ else
+ print('error: ', error)") ReadCStringFromMemory;
size_t
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.
- Returns the unsigned integer that was read. Example:
+ Returns the unsigned integer that was read. Example: ::
- # Read a 4 byte unsigned integer from address 0x1000
- error = lldb.SBError()
- uint = ReadUnsignedFromMemory(0x1000, 4, error)
- if error.Success():
- print('integer: %u' % uint)
- else
- print('error: ', error)") ReadUnsignedFromMemory;
+ # Read a 4 byte unsigned integer from address 0x1000
+ error = lldb.SBError()
+ uint = ReadUnsignedFromMemory(0x1000, 4, error)
+ if error.Success():
+ print('integer: %u' % uint)
+ else
+ print('error: ', error)") ReadUnsignedFromMemory;
uint64_t
ReadUnsignedFromMemory (addr_t addr, uint32_t byte_size, lldb::SBError &error);
%feature("autodoc", "
- Reads a pointer from memory from an address and returns the value. Example:
+ Reads a pointer from memory from an address and returns the value. Example: ::
- # Read a pointer from address 0x1000
- error = lldb.SBError()
- ptr = ReadPointerFromMemory(0x1000, error)
- if error.Success():
- print('pointer: 0x%x' % ptr)
- else
- print('error: ', error)") ReadPointerFromMemory;
+ # Read a pointer from address 0x1000
+ error = lldb.SBError()
+ ptr = ReadPointerFromMemory(0x1000, error)
+ if error.Success():
+ print('pointer: 0x%x' % ptr)
+ else
+ print('error: ', error)") ReadPointerFromMemory;
lldb::addr_t
ReadPointerFromMemory (addr_t addr, lldb::SBError &error);
@@ -414,11 +412,11 @@ public:
%feature("autodoc", "
Get information about the process.
Valid process info will only be returned when the process is alive,
- use IsValid() to check if the info returned is valid.
+ use IsValid() to check if the info returned is valid. ::
- process_info = process.GetProcessInfo()
- if process_info.IsValid():
- process_info.GetProcessID()") GetProcessInfo;
+ process_info = process.GetProcessInfo()
+ if process_info.IsValid():
+ process_info.GetProcessID()") GetProcessInfo;
lldb::SBProcessInfo
GetProcessInfo();
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBQueue.i b/contrib/llvm-project/lldb/bindings/interface/SBQueue.i
index f209d59f1bf9..9f2ec56b241c 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBQueue.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBQueue.i
@@ -8,6 +8,9 @@
namespace lldb {
+%feature("docstring",
+"Represents a libdispatch queue in the process."
+) SBQueue;
class SBQueue
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBQueueItem.i b/contrib/llvm-project/lldb/bindings/interface/SBQueueItem.i
index 089771e80378..2270d958e17d 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBQueueItem.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBQueueItem.i
@@ -8,6 +8,9 @@
namespace lldb {
+%feature("docstring",
+"This class represents an item in an :py:class:`SBQueue`."
+) SBQueueItem;
class SBQueueItem
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBReproducer.i b/contrib/llvm-project/lldb/bindings/interface/SBReproducer.i
index 7c9b007db3c0..bc9a5bab3cfa 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBReproducer.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBReproducer.i
@@ -7,6 +7,10 @@
//===----------------------------------------------------------------------===//
namespace lldb {
+
+%feature("docstring",
+"Controls LLDB's reproducer functionality."
+) SBReproducer;
class SBReproducer
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBSection.i b/contrib/llvm-project/lldb/bindings/interface/SBSection.i
index 3d1c900917fd..b86d4e99c5ea 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBSection.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBSection.i
@@ -12,7 +12,7 @@ namespace lldb {
"Represents an executable image section.
SBSection supports iteration through its subsection, represented as SBSection
-as well. For example,
+as well. For example, ::
for sec in exe_module:
if sec.GetName() == '__TEXT':
@@ -22,18 +22,18 @@ as well. For example,
for subsec in sec:
print INDENT + repr(subsec)
-produces:
+produces: ::
-[0x0000000100000000-0x0000000100002000) a.out.__TEXT
- Number of subsections: 6
- [0x0000000100001780-0x0000000100001d5c) a.out.__TEXT.__text
- [0x0000000100001d5c-0x0000000100001da4) a.out.__TEXT.__stubs
- [0x0000000100001da4-0x0000000100001e2c) a.out.__TEXT.__stub_helper
- [0x0000000100001e2c-0x0000000100001f10) a.out.__TEXT.__cstring
- [0x0000000100001f10-0x0000000100001f68) a.out.__TEXT.__unwind_info
- [0x0000000100001f68-0x0000000100001ff8) a.out.__TEXT.__eh_frame
+ [0x0000000100000000-0x0000000100002000) a.out.__TEXT
+ Number of subsections: 6
+ [0x0000000100001780-0x0000000100001d5c) a.out.__TEXT.__text
+ [0x0000000100001d5c-0x0000000100001da4) a.out.__TEXT.__stubs
+ [0x0000000100001da4-0x0000000100001e2c) a.out.__TEXT.__stub_helper
+ [0x0000000100001e2c-0x0000000100001f10) a.out.__TEXT.__cstring
+ [0x0000000100001f10-0x0000000100001f68) a.out.__TEXT.__unwind_info
+ [0x0000000100001f68-0x0000000100001ff8) a.out.__TEXT.__eh_frame
-See also SBModule."
+See also :py:class:`SBModule` ."
) SBSection;
class SBSection
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBSourceManager.i b/contrib/llvm-project/lldb/bindings/interface/SBSourceManager.i
index dfbdc612a06e..12dd1bdb0d18 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBSourceManager.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBSourceManager.i
@@ -11,7 +11,7 @@ namespace lldb {
%feature("docstring",
"Represents a central authority for displaying source code.
-For example (from test/source-manager/TestSourceManager.py),
+For example (from test/source-manager/TestSourceManager.py), ::
# Create the filespec for 'main.c'.
filespec = lldb.SBFileSpec('main.c', False)
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBStream.i b/contrib/llvm-project/lldb/bindings/interface/SBStream.i
index edd67f87c3fb..acf44e351d5f 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBStream.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBStream.i
@@ -14,7 +14,7 @@ namespace lldb {
"Represents a destination for streaming data output to. By default, a string
stream is created.
-For example (from test/source-manager/TestSourceManager.py),
+For example (from test/source-manager/TestSourceManager.py), ::
# Create the filespec for 'main.c'.
filespec = lldb.SBFileSpec('main.c', False)
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBStringList.i b/contrib/llvm-project/lldb/bindings/interface/SBStringList.i
index c8e1e357ed2b..d80ae9f9c5b9 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBStringList.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBStringList.i
@@ -8,6 +8,9 @@
namespace lldb {
+%feature("docstring",
+"Represents a list of strings."
+) SBStringList;
class SBStringList
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBStructuredData.i b/contrib/llvm-project/lldb/bindings/interface/SBStructuredData.i
index c7601bf6cf95..5aba35229855 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBStructuredData.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBStructuredData.i
@@ -8,12 +8,11 @@
namespace lldb {
- %feature("docstring",
- "A class representing a StructuredData event.
+%feature("docstring",
+ "A class representing a StructuredData event.
- This class wraps the event type generated by StructuredData
- features."
- ) SBStructuredData;
+This class wraps the event type generated by StructuredData features."
+) SBStructuredData;
class SBStructuredData
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBSymbol.i b/contrib/llvm-project/lldb/bindings/interface/SBSymbol.i
index 4e17ab5af0fd..fa0b3e4e1378 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBSymbol.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBSymbol.i
@@ -10,9 +10,7 @@ namespace lldb {
%feature("docstring",
"Represents the symbol possibly associated with a stack frame.
-SBModule contains SBSymbol(s). SBSymbol can also be retrieved from SBFrame.
-
-See also SBModule and SBFrame."
+:py:class:`SBModule` contains SBSymbol(s). SBSymbol can also be retrieved from :py:class:`SBFrame` ."
) SBSymbol;
class SBSymbol
{
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBSymbolContext.i b/contrib/llvm-project/lldb/bindings/interface/SBSymbolContext.i
index b6b336516c94..9818fdb09498 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBSymbolContext.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBSymbolContext.i
@@ -15,7 +15,7 @@ Many debugger functions require a context when doing lookups. This class
provides a common structure that can be used as the result of a query that
can contain a single result.
-For example,
+For example, ::
exe = os.path.join(os.getcwd(), 'a.out')
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBSymbolContextList.i b/contrib/llvm-project/lldb/bindings/interface/SBSymbolContextList.i
index f5adcfcebfb5..e9d4aa8d62db 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBSymbolContextList.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBSymbolContextList.i
@@ -11,7 +11,7 @@ namespace lldb {
%feature("docstring",
"Represents a list of symbol context object. See also SBSymbolContext.
-For example (from test/python_api/target/TestTargetAPI.py),
+For example (from test/python_api/target/TestTargetAPI.py), ::
def find_functions(self, exe_name):
'''Exercise SBTaget.FindFunctions() API.'''
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBTarget.i b/contrib/llvm-project/lldb/bindings/interface/SBTarget.i
index 57b5ccea6399..f874726b42d8 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBTarget.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBTarget.i
@@ -11,40 +11,40 @@ namespace lldb {
%feature("docstring",
"Represents the target program running under the debugger.
-SBTarget supports module, breakpoint, and watchpoint iterations. For example,
+SBTarget supports module, breakpoint, and watchpoint iterations. For example, ::
for m in target.module_iter():
print m
-produces:
+produces: ::
-(x86_64) /Volumes/data/lldb/svn/trunk/test/python_api/lldbutil/iter/a.out
-(x86_64) /usr/lib/dyld
-(x86_64) /usr/lib/libstdc++.6.dylib
-(x86_64) /usr/lib/libSystem.B.dylib
-(x86_64) /usr/lib/system/libmathCommon.A.dylib
-(x86_64) /usr/lib/libSystem.B.dylib(__commpage)
+ (x86_64) /Volumes/data/lldb/svn/trunk/test/python_api/lldbutil/iter/a.out
+ (x86_64) /usr/lib/dyld
+ (x86_64) /usr/lib/libstdc++.6.dylib
+ (x86_64) /usr/lib/libSystem.B.dylib
+ (x86_64) /usr/lib/system/libmathCommon.A.dylib
+ (x86_64) /usr/lib/libSystem.B.dylib(__commpage)
-and,
+and, ::
for b in target.breakpoint_iter():
print b
-produces:
+produces: ::
-SBBreakpoint: id = 1, file ='main.cpp', line = 66, locations = 1
-SBBreakpoint: id = 2, file ='main.cpp', line = 85, locations = 1
+ SBBreakpoint: id = 1, file ='main.cpp', line = 66, locations = 1
+ SBBreakpoint: id = 2, file ='main.cpp', line = 85, locations = 1
-and,
+and, ::
for wp_loc in target.watchpoint_iter():
print wp_loc
-produces:
+produces: ::
-Watchpoint 1: addr = 0x1034ca048 size = 4 state = enabled type = rw
- declare @ '/Volumes/data/lldb/svn/trunk/test/python_api/watchpoint/main.c:12'
- hw_index = 0 hit_count = 2 ignore_count = 0"
+ Watchpoint 1: addr = 0x1034ca048 size = 4 state = enabled type = rw
+ declare @ '/Volumes/data/lldb/svn/trunk/test/python_api/watchpoint/main.c:12'
+ hw_index = 0 hit_count = 2 ignore_count = 0"
) SBTarget;
class SBTarget
{
@@ -208,30 +208,16 @@ public:
%feature("docstring", "
Launch a new process with sensible defaults.
- @param[in] argv
- The argument array.
-
- @param[in] envp
- The environment array.
-
- @param[in] working_directory
- The working directory to have the child process run in
+ :param argv: The argument array.
+ :param envp: The environment array.
+ :param working_directory: The working directory to have the child process run in
+ :return: The newly created process.
+ :rtype: SBProcess
- Default: listener
- Set to the target's debugger (SBTarget::GetDebugger())
+ A pseudo terminal will be used as stdin/stdout/stderr.
+ No launch flags are passed and the target's debuger is used as a listener.
- Default: launch_flags
- Empty launch flags
-
- Default: stdin_path
- Default: stdout_path
- Default: stderr_path
- A pseudo terminal will be used.
-
- @return
- A process object for the newly created process.
-
- For example,
+ For example, ::
process = target.LaunchSimple(['X', 'Y', 'Z'], None, os.getcwd())
@@ -389,16 +375,13 @@ public:
FindModule (const lldb::SBFileSpec &file_spec);
%feature("docstring", "
- Find compile units related to *this target and passed source
+ Find compile units related to this target and passed source
file.
- @param[in] sb_file_spec
- A lldb::SBFileSpec object that contains source file
+ :param sb_file_spec: A :py:class:`lldb::SBFileSpec` object that contains source file
specification.
-
- @return
- A lldb::SBSymbolContextList that gets filled in with all of
- the symbol contexts for all the matches.") FindCompileUnits;
+ :return: The symbol contexts for all the matches.
+ :rtype: SBSymbolContextList") FindCompileUnits;
lldb::SBSymbolContextList
FindCompileUnits (const lldb::SBFileSpec &sb_file_spec);
@@ -414,18 +397,18 @@ public:
%feature("docstring", "
Architecture data byte width accessor
- @return
- The size in 8-bit (host) bytes of a minimum addressable
- unit from the Architecture's data bus") GetDataByteSize;
+ :return: The size in 8-bit (host) bytes of a minimum addressable unit from the Architecture's data bus.
+
+ ") GetDataByteSize;
uint32_t
GetDataByteSize ();
%feature("docstring", "
- Architecture code byte width accessor
+ Architecture code byte width accessor.
- @return
- The size in 8-bit (host) bytes of a minimum addressable
- unit from the Architecture's code bus") GetCodeByteSize;
+ :return: The size in 8-bit (host) bytes of a minimum addressable unit from the Architecture's code bus.
+
+ ") GetCodeByteSize;
uint32_t
GetCodeByteSize ();
@@ -446,17 +429,16 @@ public:
%feature("docstring", "
Find functions by name.
- @param[in] name
- The name of the function we are looking for.
+ :param name: The name of the function we are looking for.
- @param[in] name_type_mask
+ :param name_type_mask:
A logical OR of one or more FunctionNameType enum bits that
indicate what kind of names should be used when doing the
lookup. Bits include fully qualified names, base names,
C++ methods, or ObjC selectors.
See FunctionNameType for more details.
- @return
+ :return:
A lldb::SBSymbolContextList that gets filled in with all of
the symbol contexts for all the matches.") FindFunctions;
lldb::SBSymbolContextList
@@ -580,6 +562,12 @@ public:
SBFileSpecList &module_list);
lldb::SBBreakpoint
+ BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line,
+ uint32_t column, lldb::addr_t offset,
+ SBFileSpecList &module_list,
+ bool move_to_nearest_code);
+
+ lldb::SBBreakpoint
BreakpointCreateByName (const char *symbol_name, const char *module_name = NULL);
lldb::SBBreakpoint
@@ -688,41 +676,42 @@ public:
@param[in] class_name
This is the name of the class that implements a scripted resolver.
- The class should have the following signature:
- class Resolver:
- def __init__(self, bkpt, extra_args):
- # bkpt - the breakpoint for which this is the resolver. When
- # the resolver finds an interesting address, call AddLocation
- # on this breakpoint to add it.
- #
- # extra_args - an SBStructuredData that can be used to
- # parametrize this instance. Same as the extra_args passed
- # to BreakpointCreateFromScript.
-
- def __get_depth__ (self):
- # This is optional, but if defined, you should return the
- # depth at which you want the callback to be called. The
- # available options are:
- # lldb.eSearchDepthModule
- # lldb.eSearchDepthCompUnit
- # The default if you don't implement this method is
- # eSearchDepthModule.
-
- def __callback__(self, sym_ctx):
- # sym_ctx - an SBSymbolContext that is the cursor in the
- # search through the program to resolve breakpoints.
- # The sym_ctx will be filled out to the depth requested in
- # __get_depth__.
- # Look in this sym_ctx for new breakpoint locations,
- # and if found use bkpt.AddLocation to add them.
- # Note, you will only get called for modules/compile_units that
- # pass the SearchFilter provided by the module_list & file_list
- # passed into BreakpointCreateFromScript.
-
- def get_short_help(self):
- # Optional, but if implemented return a short string that will
- # be printed at the beginning of the break list output for the
- # breakpoint.
+ The class should have the following signature: ::
+
+ class Resolver:
+ def __init__(self, bkpt, extra_args):
+ # bkpt - the breakpoint for which this is the resolver. When
+ # the resolver finds an interesting address, call AddLocation
+ # on this breakpoint to add it.
+ #
+ # extra_args - an SBStructuredData that can be used to
+ # parametrize this instance. Same as the extra_args passed
+ # to BreakpointCreateFromScript.
+
+ def __get_depth__ (self):
+ # This is optional, but if defined, you should return the
+ # depth at which you want the callback to be called. The
+ # available options are:
+ # lldb.eSearchDepthModule
+ # lldb.eSearchDepthCompUnit
+ # The default if you don't implement this method is
+ # eSearchDepthModule.
+
+ def __callback__(self, sym_ctx):
+ # sym_ctx - an SBSymbolContext that is the cursor in the
+ # search through the program to resolve breakpoints.
+ # The sym_ctx will be filled out to the depth requested in
+ # __get_depth__.
+ # Look in this sym_ctx for new breakpoint locations,
+ # and if found use bkpt.AddLocation to add them.
+ # Note, you will only get called for modules/compile_units that
+ # pass the SearchFilter provided by the module_list & file_list
+ # passed into BreakpointCreateFromScript.
+
+ def get_short_help(self):
+ # Optional, but if implemented return a short string that will
+ # be printed at the beginning of the break list output for the
+ # breakpoint.
@param[in] extra_args
This is an SBStructuredData object that will get passed to the
@@ -902,11 +891,12 @@ public:
%feature("docstring", "
Disassemble a specified number of instructions starting at an address.
- Parameters:
- base_addr -- the address to start disassembly from
- count -- the number of instructions to disassemble
- flavor_string -- may be 'intel' or 'att' on x86 targets to specify that style of disassembly
- Returns an SBInstructionList.")
+
+ :param base_addr: the address to start disassembly from.
+ :param count: the number of instructions to disassemble.
+ :param flavor_string: may be 'intel' or 'att' on x86 targets to specify that style of disassembly.
+ :rtype: SBInstructionList
+ ")
ReadInstructions;
lldb::SBInstructionList
ReadInstructions (lldb::SBAddress base_addr, uint32_t count);
@@ -916,23 +906,25 @@ public:
%feature("docstring", "
Disassemble the bytes in a buffer and return them in an SBInstructionList.
- Parameters:
- base_addr -- used for symbolicating the offsets in the byte stream when disassembling
- buf -- bytes to be disassembled
- size -- (C++) size of the buffer
- Returns an SBInstructionList.")
+
+ :param base_addr: used for symbolicating the offsets in the byte stream when disassembling.
+ :param buf: bytes to be disassembled.
+ :param size: (C++) size of the buffer.
+ :rtype: SBInstructionList
+ ")
GetInstructions;
lldb::SBInstructionList
GetInstructions (lldb::SBAddress base_addr, const void *buf, size_t size);
%feature("docstring", "
Disassemble the bytes in a buffer and return them in an SBInstructionList, with a supplied flavor.
- Parameters:
- base_addr -- used for symbolicating the offsets in the byte stream when disassembling
- flavor -- may be 'intel' or 'att' on x86 targets to specify that style of disassembly
- buf -- bytes to be disassembled
- size -- (C++) size of the buffer
- Returns an SBInstructionList.")
+
+ :param base_addr: used for symbolicating the offsets in the byte stream when disassembling.
+ :param flavor: may be 'intel' or 'att' on x86 targets to specify that style of disassembly.
+ :param buf: bytes to be disassembled.
+ :param size: (C++) size of the buffer.
+ :rtype: SBInstructionList
+ ")
GetInstructionsWithFlavor;
lldb::SBInstructionList
GetInstructionsWithFlavor (lldb::SBAddress base_addr, const char *flavor_string, const void *buf, size_t size);
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBThread.i b/contrib/llvm-project/lldb/bindings/interface/SBThread.i
index 66466b7947fd..463584d2cab1 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBThread.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBThread.i
@@ -9,7 +9,7 @@
namespace lldb {
%feature("docstring",
-"Represents a thread of execution. SBProcess contains SBThread(s).
+"Represents a thread of execution. :py:class:`SBProcess` contains SBThread(s).
SBThreads can be referred to by their ID, which maps to the system specific thread
identifier, or by IndexID. The ID may or may not be unique depending on whether the
@@ -18,7 +18,7 @@ that will always uniquely reference a particular thread, and when that thread go
away it will not be reused.
SBThread supports frame iteration. For example (from test/python_api/
-lldbutil/iter/TestLLDBIterator.py),
+lldbutil/iter/TestLLDBIterator.py), ::
from lldbutil import print_stacktrace
stopped_due_to_breakpoint = False
@@ -35,7 +35,7 @@ lldbutil/iter/TestLLDBIterator.py),
self.assertTrue(stopped_due_to_breakpoint)
-See also SBProcess and SBFrame."
+See also :py:class:`SBFrame` ."
) SBThread;
class SBThread
{
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBThreadPlan.i b/contrib/llvm-project/lldb/bindings/interface/SBThreadPlan.i
index 36131d529b7b..94ae1a42dd3b 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBThreadPlan.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBThreadPlan.i
@@ -18,8 +18,8 @@ namespace lldb {
%feature("docstring",
"Represents a plan for the execution control of a given thread.
-See also SBThread and SBFrame."
-) SBThread;
+See also :py:class:`SBThread` and :py:class:`SBFrame`."
+) SBThreadPlan;
class SBThreadPlan
{
@@ -92,6 +92,14 @@ public:
bool
IsPlanStale();
+ %feature("docstring", "Return whether this plan will ask to stop other threads when it runs.") GetStopOthers;
+ bool
+ GetStopOthers();
+
+ %feature("docstring", "Set whether this plan will ask to stop other threads when it runs.") GetStopOthers;
+ void
+ SetStopOthers(bool stop_others);
+
SBThreadPlan
QueueThreadPlanForStepOverRange (SBAddress &start_address,
lldb::addr_t range_size);
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBTrace.i b/contrib/llvm-project/lldb/bindings/interface/SBTrace.i
index a4cb2667ec10..6d4b7e6be27d 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBTrace.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBTrace.i
@@ -8,6 +8,9 @@
namespace lldb {
+%feature("docstring",
+"Represents a processor trace."
+) SBTrace;
class LLDB_API SBTrace {
public:
SBTrace();
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBTraceOptions.i b/contrib/llvm-project/lldb/bindings/interface/SBTraceOptions.i
index ce17af5376ca..4a1878b5b76f 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBTraceOptions.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBTraceOptions.i
@@ -8,6 +8,11 @@
namespace lldb {
+%feature("docstring",
+"Represents the possible options when doing processor tracing.
+
+See :py:class:`SBProcess.StartTrace`."
+) SBTraceOptions;
class LLDB_API SBTraceOptions {
public:
SBTraceOptions();
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBType.i b/contrib/llvm-project/lldb/bindings/interface/SBType.i
index 3cd82452084b..e7b3fd11e338 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBType.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBType.i
@@ -9,7 +9,7 @@
namespace lldb {
%feature("docstring",
-"Represents a member of a type in lldb.") SBTypeMember;
+"Represents a member of a type.") SBTypeMember;
class SBTypeMember
{
@@ -60,6 +60,9 @@ protected:
std::unique_ptr<lldb_private::TypeMemberImpl> m_opaque_ap;
};
+%feature("docstring",
+"Represents a member function of a type."
+) SBTypeMemberFunction;
class SBTypeMemberFunction
{
public:
@@ -111,72 +114,72 @@ protected:
"Represents a data type in lldb. The FindFirstType() method of SBTarget/SBModule
returns a SBType.
-SBType supports the eq/ne operator. For example,
-
-main.cpp:
-
-class Task {
-public:
- int id;
- Task *next;
- Task(int i, Task *n):
- id(i),
- next(n)
- {}
-};
-
-int main (int argc, char const *argv[])
-{
- Task *task_head = new Task(-1, NULL);
- Task *task1 = new Task(1, NULL);
- Task *task2 = new Task(2, NULL);
- Task *task3 = new Task(3, NULL); // Orphaned.
- Task *task4 = new Task(4, NULL);
- Task *task5 = new Task(5, NULL);
-
- task_head->next = task1;
- task1->next = task2;
- task2->next = task4;
- task4->next = task5;
-
- int total = 0;
- Task *t = task_head;
- while (t != NULL) {
- if (t->id >= 0)
- ++total;
- t = t->next;
+SBType supports the eq/ne operator. For example,::
+
+ //main.cpp:
+
+ class Task {
+ public:
+ int id;
+ Task *next;
+ Task(int i, Task *n):
+ id(i),
+ next(n)
+ {}
+ };
+
+ int main (int argc, char const *argv[])
+ {
+ Task *task_head = new Task(-1, NULL);
+ Task *task1 = new Task(1, NULL);
+ Task *task2 = new Task(2, NULL);
+ Task *task3 = new Task(3, NULL); // Orphaned.
+ Task *task4 = new Task(4, NULL);
+ Task *task5 = new Task(5, NULL);
+
+ task_head->next = task1;
+ task1->next = task2;
+ task2->next = task4;
+ task4->next = task5;
+
+ int total = 0;
+ Task *t = task_head;
+ while (t != NULL) {
+ if (t->id >= 0)
+ ++total;
+ t = t->next;
+ }
+ printf('We have a total number of %d tasks\\n', total);
+
+ // This corresponds to an empty task list.
+ Task *empty_task_head = new Task(-1, NULL);
+
+ return 0; // Break at this line
}
- printf('We have a total number of %d tasks\\n', total);
-
- // This corresponds to an empty task list.
- Task *empty_task_head = new Task(-1, NULL);
-
- return 0; // Break at this line
-}
-find_type.py:
+ # find_type.py:
- # Get the type 'Task'.
- task_type = target.FindFirstType('Task')
- self.assertTrue(task_type)
+ # Get the type 'Task'.
+ task_type = target.FindFirstType('Task')
+ self.assertTrue(task_type)
- # Get the variable 'task_head'.
- frame0.FindVariable('task_head')
- task_head_type = task_head.GetType()
- self.assertTrue(task_head_type.IsPointerType())
+ # Get the variable 'task_head'.
+ frame0.FindVariable('task_head')
+ task_head_type = task_head.GetType()
+ self.assertTrue(task_head_type.IsPointerType())
- # task_head_type is 'Task *'.
- task_pointer_type = task_type.GetPointerType()
- self.assertTrue(task_head_type == task_pointer_type)
+ # task_head_type is 'Task *'.
+ task_pointer_type = task_type.GetPointerType()
+ self.assertTrue(task_head_type == task_pointer_type)
- # Get the child mmember 'id' from 'task_head'.
- id = task_head.GetChildMemberWithName('id')
- id_type = id.GetType()
+ # Get the child mmember 'id' from 'task_head'.
+ id = task_head.GetChildMemberWithName('id')
+ id_type = id.GetType()
- # SBType.GetBasicType() takes an enum 'BasicType' (lldb-enumerations.h).
- int_type = id_type.GetBasicType(lldb.eBasicTypeInt)
- # id_type and int_type should be the same type!
- self.assertTrue(id_type == int_type)
+ # SBType.GetBasicType() takes an enum 'BasicType' (lldb-enumerations.h).
+ int_type = id_type.GetBasicType(lldb.eBasicTypeInt)
+ # id_type and int_type should be the same type!
+ self.assertTrue(id_type == int_type)
...") SBType;
class SBType
@@ -220,6 +223,9 @@ public:
bool
IsAnonymousType ();
+ bool
+ IsScopedEnumerationType ();
+
lldb::SBType
GetPointerType();
@@ -242,6 +248,9 @@ public:
GetCanonicalType();
lldb::SBType
+ GetEnumerationIntegerType();
+
+ lldb::SBType
GetArrayElementType ();
lldb::SBType
@@ -277,6 +286,9 @@ public:
lldb::SBTypeEnumMemberList
GetEnumMembers();
+ lldb::SBModule
+ GetModule();
+
const char*
GetName();
@@ -330,6 +342,7 @@ public:
return template_args
return None
+ module = property(GetModule, None, doc='''A read only property that returns the module in which type is defined.''')
name = property(GetName, None, doc='''A read only property that returns the name for this type as a string.''')
size = property(GetByteSize, None, doc='''A read only property that returns size in bytes for this type as an integer.''')
is_pointer = property(IsPointerType, None, doc='''A read only property that returns a boolean value that indicates if this type is a pointer type.''')
@@ -421,35 +434,38 @@ public:
};
%feature("docstring",
-"Represents a list of SBTypes. The FindTypes() method of SBTarget/SBModule
-returns a SBTypeList.
+"Represents a list of :py:class:`SBType` s.
-SBTypeList supports SBType iteration. For example,
+The FindTypes() method of :py:class:`SBTarget`/:py:class:`SBModule` returns a SBTypeList.
-main.cpp:
+SBTypeList supports :py:class:`SBType` iteration. For example,
-class Task {
-public:
- int id;
- Task *next;
- Task(int i, Task *n):
- id(i),
- next(n)
- {}
-};
+.. code-block:: cpp
+
+ // main.cpp:
+
+ class Task {
+ public:
+ int id;
+ Task *next;
+ Task(int i, Task *n):
+ id(i),
+ next(n)
+ {}
+ };
-...
+.. code-block:: python
-find_type.py:
+ # find_type.py:
- # Get the type 'Task'.
- type_list = target.FindTypes('Task')
- self.assertTrue(len(type_list) == 1)
- # To illustrate the SBType iteration.
- for type in type_list:
- # do something with type
+ # Get the type 'Task'.
+ type_list = target.FindTypes('Task')
+ self.assertTrue(len(type_list) == 1)
+ # To illustrate the SBType iteration.
+ for type in type_list:
+ # do something with type
-...") SBTypeList;
+") SBTypeList;
class SBTypeList
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBTypeEnumMember.i b/contrib/llvm-project/lldb/bindings/interface/SBTypeEnumMember.i
index 006bdeaa8cee..b41901027245 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBTypeEnumMember.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBTypeEnumMember.i
@@ -71,10 +71,19 @@ protected:
SBTypeEnumMember (const lldb::TypeEnumMemberImplSP &);
};
-%feature(
- "docstring",
- "Represents a list of SBTypeEnumMembers."
-) SBTypeEnumMemberList;
+%feature("docstring",
+"Represents a list of SBTypeEnumMembers.
+
+SBTypeEnumMemberList supports SBTypeEnumMember iteration.
+It also supports [] access either by index, or by enum
+element name by doing: ::
+
+ myType = target.FindFirstType('MyEnumWithElementA')
+ members = myType.GetEnumMembers()
+ first_elem = members[0]
+ elem_A = members['A']
+
+") SBTypeEnumMemberList;
class SBTypeEnumMemberList
{
@@ -99,6 +108,29 @@ public:
uint32_t
GetSize();
+#ifdef SWIGPYTHON
+ %pythoncode %{
+ def __iter__(self):
+ '''Iterate over all members in a lldb.SBTypeEnumMemberList object.'''
+ return lldb_iter(self, 'GetSize', 'GetTypeEnumMemberAtIndex')
+
+ def __len__(self):
+ '''Return the number of members in a lldb.SBTypeEnumMemberList object.'''
+ return self.GetSize()
+
+ def __getitem__(self, key):
+ num_elements = self.GetSize()
+ if type(key) is int:
+ if key < num_elements:
+ return self.GetTypeEnumMemberAtIndex(key)
+ elif type(key) is str:
+ for idx in range(num_elements):
+ item = self.GetTypeEnumMemberAtIndex(idx)
+ if item.name == key:
+ return item
+ return None
+ %}
+#endif
private:
std::unique_ptr<lldb_private::TypeEnumMemberListImpl> m_opaque_ap;
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBValue.i b/contrib/llvm-project/lldb/bindings/interface/SBValue.i
index fb899805c395..dd012e667a20 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBValue.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBValue.i
@@ -13,7 +13,7 @@ namespace lldb {
SBValue supports iteration through its child, which in turn is represented
as an SBValue. For example, we can get the general purpose registers of a
-frame as an SBValue, and iterate through all the registers,
+frame as an SBValue, and iterate through all the registers,::
registerSet = frame.registers # Returns an SBValueList.
for regs in registerSet:
@@ -25,30 +25,30 @@ frame as an SBValue, and iterate through all the registers,
for reg in GPRs:
print('Name: ', reg.name, ' Value: ', reg.value)
-produces the output:
-
-General Purpose Registers (number of children = 21):
-Name: rax Value: 0x0000000100000c5c
-Name: rbx Value: 0x0000000000000000
-Name: rcx Value: 0x00007fff5fbffec0
-Name: rdx Value: 0x00007fff5fbffeb8
-Name: rdi Value: 0x0000000000000001
-Name: rsi Value: 0x00007fff5fbffea8
-Name: rbp Value: 0x00007fff5fbffe80
-Name: rsp Value: 0x00007fff5fbffe60
-Name: r8 Value: 0x0000000008668682
-Name: r9 Value: 0x0000000000000000
-Name: r10 Value: 0x0000000000001200
-Name: r11 Value: 0x0000000000000206
-Name: r12 Value: 0x0000000000000000
-Name: r13 Value: 0x0000000000000000
-Name: r14 Value: 0x0000000000000000
-Name: r15 Value: 0x0000000000000000
-Name: rip Value: 0x0000000100000dae
-Name: rflags Value: 0x0000000000000206
-Name: cs Value: 0x0000000000000027
-Name: fs Value: 0x0000000000000010
-Name: gs Value: 0x0000000000000048
+produces the output: ::
+
+ General Purpose Registers (number of children = 21):
+ Name: rax Value: 0x0000000100000c5c
+ Name: rbx Value: 0x0000000000000000
+ Name: rcx Value: 0x00007fff5fbffec0
+ Name: rdx Value: 0x00007fff5fbffeb8
+ Name: rdi Value: 0x0000000000000001
+ Name: rsi Value: 0x00007fff5fbffea8
+ Name: rbp Value: 0x00007fff5fbffe80
+ Name: rsp Value: 0x00007fff5fbffe60
+ Name: r8 Value: 0x0000000008668682
+ Name: r9 Value: 0x0000000000000000
+ Name: r10 Value: 0x0000000000001200
+ Name: r11 Value: 0x0000000000000206
+ Name: r12 Value: 0x0000000000000000
+ Name: r13 Value: 0x0000000000000000
+ Name: r14 Value: 0x0000000000000000
+ Name: r15 Value: 0x0000000000000000
+ Name: rip Value: 0x0000000100000dae
+ Name: rflags Value: 0x0000000000000206
+ Name: cs Value: 0x0000000000000027
+ Name: fs Value: 0x0000000000000010
+ Name: gs Value: 0x0000000000000048
See also linked_list_iter() for another perspective on how to iterate through an
SBValue instance which interprets the value object as representing the head of a
@@ -379,22 +379,18 @@ public:
Get an SBData wrapping what this SBValue points to.
This method will dereference the current SBValue, if its
- data type is a T* or T[], and extract item_count elements
- of type T from it, copying their contents in an SBData.
+ data type is a ``T\*`` or ``T[]``, and extract ``item_count`` elements
+ of type ``T`` from it, copying their contents in an :py:class:`SBData`.
- @param[in] item_idx
- The index of the first item to retrieve. For an array
+ :param item_idx: The index of the first item to retrieve. For an array
this is equivalent to array[item_idx], for a pointer
- to *(pointer + item_idx). In either case, the measurement
- unit for item_idx is the sizeof(T) rather than the byte
-
- @param[in] item_count
- How many items should be copied into the output. By default
+ to ``\*(pointer + item_idx)``. In either case, the measurement
+ unit for item_idx is the ``sizeof(T)`` rather than the byte
+ :param item_count: How many items should be copied into the output. By default
only one item is copied, but more can be asked for.
-
- @return
- An SBData with the contents of the copied items, on success.
- An empty SBData otherwise.") GetPointeeData;
+ :return: The contents of the copied items on success. An empty :py:class:`SBData` otherwise.
+ :rtype: SBData
+ ") GetPointeeData;
lldb::SBData
GetPointeeData (uint32_t item_idx = 0,
uint32_t item_count = 1);
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBValueList.i b/contrib/llvm-project/lldb/bindings/interface/SBValueList.i
index 17ba2056f0c2..76fa937b9876 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBValueList.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBValueList.i
@@ -9,61 +9,62 @@
namespace lldb {
%feature("docstring",
-"Represents a collection of SBValues. Both SBFrame's GetVariables() and
-GetRegisters() return a SBValueList.
-
-SBValueList supports SBValue iteration. For example (from test/lldbutil.py),
-
-def get_registers(frame, kind):
- '''Returns the registers given the frame and the kind of registers desired.
-
- Returns None if there's no such kind.
- '''
- registerSet = frame.GetRegisters() # Return type of SBValueList.
- for value in registerSet:
- if kind.lower() in value.GetName().lower():
- return value
-
- return None
-
-def get_GPRs(frame):
- '''Returns the general purpose registers of the frame as an SBValue.
-
- The returned SBValue object is iterable. An example:
- ...
- from lldbutil import get_GPRs
- regs = get_GPRs(frame)
- for reg in regs:
- print('%s => %s' % (reg.GetName(), reg.GetValue()))
- ...
- '''
- return get_registers(frame, 'general purpose')
-
-def get_FPRs(frame):
- '''Returns the floating point registers of the frame as an SBValue.
-
- The returned SBValue object is iterable. An example:
- ...
- from lldbutil import get_FPRs
- regs = get_FPRs(frame)
- for reg in regs:
- print('%s => %s' % (reg.GetName(), reg.GetValue()))
- ...
- '''
- return get_registers(frame, 'floating point')
-
-def get_ESRs(frame):
- '''Returns the exception state registers of the frame as an SBValue.
-
- The returned SBValue object is iterable. An example:
- ...
- from lldbutil import get_ESRs
- regs = get_ESRs(frame)
- for reg in regs:
- print('%s => %s' % (reg.GetName(), reg.GetValue()))
- ...
- '''
- return get_registers(frame, 'exception state')"
+"Represents a collection of SBValues. Both :py:class:`SBFrame.GetVariables()` and
+:py:class:`SBFrame.GetRegisters()` return a SBValueList.
+
+SBValueList supports :py:class:`SBValue` iteration. For example (from test/lldbutil.py),::
+
+ def get_registers(frame, kind):
+ '''Returns the registers given the frame and the kind of registers desired.
+
+ Returns None if there's no such kind.
+ '''
+ registerSet = frame.GetRegisters() # Return type of SBValueList.
+ for value in registerSet:
+ if kind.lower() in value.GetName().lower():
+ return value
+
+ return None
+
+ def get_GPRs(frame):
+ '''Returns the general purpose registers of the frame as an SBValue.
+
+ The returned SBValue object is iterable. An example:
+ ...
+ from lldbutil import get_GPRs
+ regs = get_GPRs(frame)
+ for reg in regs:
+ print('%s => %s' % (reg.GetName(), reg.GetValue()))
+ ...
+ '''
+ return get_registers(frame, 'general purpose')
+
+ def get_FPRs(frame):
+ '''Returns the floating point registers of the frame as an SBValue.
+
+ The returned SBValue object is iterable. An example:
+ ...
+ from lldbutil import get_FPRs
+ regs = get_FPRs(frame)
+ for reg in regs:
+ print('%s => %s' % (reg.GetName(), reg.GetValue()))
+ ...
+ '''
+ return get_registers(frame, 'floating point')
+
+ def get_ESRs(frame):
+ '''Returns the exception state registers of the frame as an SBValue.
+
+ The returned SBValue object is iterable. An example:
+ ...
+ from lldbutil import get_ESRs
+ regs = get_ESRs(frame)
+ for reg in regs:
+ print('%s => %s' % (reg.GetName(), reg.GetValue()))
+ ...
+ '''
+ return get_registers(frame, 'exception state')
+"
) SBValueList;
class SBValueList
{
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBVariablesOptions.i b/contrib/llvm-project/lldb/bindings/interface/SBVariablesOptions.i
index 362f7159d7d2..dfdc8cf5df68 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBVariablesOptions.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBVariablesOptions.i
@@ -8,6 +8,9 @@
namespace lldb {
+%feature("docstring",
+"Describes which variables should be returned from :py:class:`SBFrame.GetVariables`."
+) SBVariablesOptions;
class SBVariablesOptions
{
public:
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBWatchpoint.i b/contrib/llvm-project/lldb/bindings/interface/SBWatchpoint.i
index cb0bc5f9859a..ac31c60a5614 100644
--- a/contrib/llvm-project/lldb/bindings/interface/SBWatchpoint.i
+++ b/contrib/llvm-project/lldb/bindings/interface/SBWatchpoint.i
@@ -14,7 +14,7 @@ namespace lldb {
A watchpoint is determined by the address and the byte size that resulted in
this particular instantiation. Each watchpoint has its settable options.
-See also SBTarget.watchpoint_iter() for example usage of iterating through the
+See also :py:class:`SBTarget.watchpoint_iter()` for example usage of iterating through the
watchpoints of the target."
) SBWatchpoint;
class SBWatchpoint
diff --git a/contrib/llvm-project/lldb/bindings/lua/lua-swigsafecast.swig b/contrib/llvm-project/lldb/bindings/lua/lua-swigsafecast.swig
new file mode 100644
index 000000000000..a3ed37279546
--- /dev/null
+++ b/contrib/llvm-project/lldb/bindings/lua/lua-swigsafecast.swig
@@ -0,0 +1,21 @@
+template <typename SBClass>
+void
+PushSBClass (lua_State* L, SBClass* obj);
+
+void
+PushSBClass (lua_State* L, lldb::SBFrame* frame_sb)
+{
+ SWIG_NewPointerObj(L, frame_sb, SWIGTYPE_p_lldb__SBFrame, 0);
+}
+
+void
+PushSBClass (lua_State* L, lldb::SBBreakpointLocation* breakpoint_location_sb)
+{
+ SWIG_NewPointerObj(L, breakpoint_location_sb, SWIGTYPE_p_lldb__SBBreakpointLocation, 0);
+}
+
+void
+PushSBClass (lua_State* L, lldb::SBStructuredData* structured_data_sb)
+{
+ SWIG_NewPointerObj(L, structured_data_sb, SWIGTYPE_p_lldb__SBStructuredData, 0);
+}
diff --git a/contrib/llvm-project/lldb/bindings/lua/lua-typemaps.swig b/contrib/llvm-project/lldb/bindings/lua/lua-typemaps.swig
index 28d63fa2f402..d912137a5674 100644
--- a/contrib/llvm-project/lldb/bindings/lua/lua-typemaps.swig
+++ b/contrib/llvm-project/lldb/bindings/lua/lua-typemaps.swig
@@ -1 +1,105 @@
%include <typemaps.i>
+
+// FIXME: We need to port more typemaps from Python
+
+//===----------------------------------------------------------------------===//
+
+// In Lua 5.3 and beyond the VM supports integers, so we need to remap
+// SWIG's internal handling of integers.
+
+
+%define LLDB_NUMBER_TYPEMAP(TYPE)
+
+// Primitive integer mapping
+%typemap(in,checkfn="lua_isinteger") TYPE
+%{ $1 = (TYPE)lua_tointeger(L, $input); %}
+%typemap(in,checkfn="lua_isinteger") const TYPE&($basetype temp)
+%{ temp=($basetype)lua_tointeger(L,$input); $1=&temp;%}
+%typemap(out) TYPE
+%{ lua_pushinteger(L, (lua_Integer) $1); SWIG_arg++;%}
+%typemap(out) const TYPE&
+%{ lua_pushinteger(L, (lua_Integer) $1); SWIG_arg++;%}
+
+// Pointer and reference mapping
+%typemap(in,checkfn="lua_isinteger") TYPE *INPUT($*ltype temp), TYPE &INPUT($*ltype temp)
+%{ temp = ($*ltype)lua_tointeger(L,$input);
+ $1 = &temp; %}
+%typemap(in, numinputs=0) TYPE *OUTPUT ($*ltype temp)
+%{ $1 = &temp; %}
+%typemap(argout) TYPE *OUTPUT
+%{ lua_pushinteger(L, (lua_Integer) *$1); SWIG_arg++;%}
+%typemap(in) TYPE *INOUT = TYPE *INPUT;
+%typemap(argout) TYPE *INOUT = TYPE *OUTPUT;
+%typemap(in) TYPE &OUTPUT = TYPE *OUTPUT;
+%typemap(argout) TYPE &OUTPUT = TYPE *OUTPUT;
+%typemap(in) TYPE &INOUT = TYPE *INPUT;
+%typemap(argout) TYPE &INOUT = TYPE *OUTPUT;
+%typemap(in,checkfn="lua_isinteger") const TYPE *INPUT($*ltype temp)
+%{ temp = ($*ltype)lua_tointeger(L,$input);
+ $1 = &temp; %}
+
+%enddef // LLDB_NUMBER_TYPEMAP
+
+LLDB_NUMBER_TYPEMAP(unsigned char);
+LLDB_NUMBER_TYPEMAP(signed char);
+LLDB_NUMBER_TYPEMAP(short);
+LLDB_NUMBER_TYPEMAP(unsigned short);
+LLDB_NUMBER_TYPEMAP(signed short);
+LLDB_NUMBER_TYPEMAP(int);
+LLDB_NUMBER_TYPEMAP(unsigned int);
+LLDB_NUMBER_TYPEMAP(signed int);
+LLDB_NUMBER_TYPEMAP(long);
+LLDB_NUMBER_TYPEMAP(unsigned long);
+LLDB_NUMBER_TYPEMAP(signed long);
+LLDB_NUMBER_TYPEMAP(long long);
+LLDB_NUMBER_TYPEMAP(unsigned long long);
+LLDB_NUMBER_TYPEMAP(signed long long);
+
+%apply unsigned long { size_t };
+%apply const unsigned long & { const size_t & };
+%apply long { ssize_t };
+%apply const long & { const ssize_t & };
+
+//===----------------------------------------------------------------------===//
+
+// FIXME:
+// Ideally all the typemaps should be revisited in a future SB API revision.
+// Typemaps, usually, modifies the function signatures and might spawn
+// different LLDB APIs across languages (C++, Python, Lua...).
+// Historically, typemaps have been used to replace SWIG's deficiencies,
+// but SWIG itself evolved and some API design choices are now redundant.
+
+//===----------------------------------------------------------------------===//
+
+// Typemap definitions to allow SWIG to properly handle char buffer.
+
+// typemap for a char buffer
+%typemap(in) (char *dst, size_t dst_len) {
+ $2 = luaL_checkinteger(L, $input);
+ if ($2 <= 0) {
+ return luaL_error(L, "Positive integer expected");
+ }
+ $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
+%typemap(argout) (char *dst, size_t dst_len) {
+ lua_pop(L, 1); // Blow away the previous result
+ if ($result == 0) {
+ lua_pushliteral(L, "");
+ } else {
+ lua_pushlstring(L, (const char *)$1, $result);
+ }
+ free($1);
+ // SWIG_arg was already incremented
+}
+
+// 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);
+
+//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm-project/lldb/bindings/lua/lua-wrapper.swig b/contrib/llvm-project/lldb/bindings/lua/lua-wrapper.swig
new file mode 100644
index 000000000000..90c22920ddc1
--- /dev/null
+++ b/contrib/llvm-project/lldb/bindings/lua/lua-wrapper.swig
@@ -0,0 +1,57 @@
+%header %{
+
+template <typename T>
+void
+PushSBClass(lua_State* L, T* obj);
+
+%}
+
+%wrapper %{
+
+// This function is called from Lua::CallBreakpointCallback
+SWIGEXPORT llvm::Expected<bool>
+LLDBSwigLuaBreakpointCallbackFunction
+(
+ lua_State *L,
+ lldb::StackFrameSP stop_frame_sp,
+ lldb::BreakpointLocationSP bp_loc_sp,
+ StructuredDataImpl *extra_args_impl
+)
+{
+ lldb::SBFrame sb_frame(stop_frame_sp);
+ lldb::SBBreakpointLocation sb_bp_loc(bp_loc_sp);
+ int nargs = 2;
+
+ llvm::Optional<lldb::SBStructuredData> extra_args;
+ if (extra_args_impl)
+ extra_args = lldb::SBStructuredData(extra_args_impl);
+
+ // Push the Lua wrappers
+ PushSBClass(L, &sb_frame);
+ PushSBClass(L, &sb_bp_loc);
+
+ if (extra_args.hasValue()) {
+ PushSBClass(L, extra_args.getPointer());
+ nargs++;
+ }
+
+ // Call into the Lua callback passing 'sb_frame' and 'sb_bp_loc'.
+ // Expects a boolean return.
+ if (lua_pcall(L, nargs, 1, 0) != LUA_OK) {
+ llvm::Error E = llvm::make_error<llvm::StringError>(
+ llvm::formatv("{0}\n", lua_tostring(L, -1)),
+ llvm::inconvertibleErrorCode());
+ // Pop error message from the stack.
+ lua_pop(L, 1);
+ return std::move(E);
+ }
+
+ // Boolean return from the callback
+ bool stop = lua_toboolean(L, -1);
+ lua_pop(L, 1);
+
+ return stop;
+}
+
+
+%}
diff --git a/contrib/llvm-project/lldb/bindings/lua.swig b/contrib/llvm-project/lldb/bindings/lua/lua.swig
index 9bfc49b359bc..c702e4964081 100644
--- a/contrib/llvm-project/lldb/bindings/lua.swig
+++ b/contrib/llvm-project/lldb/bindings/lua/lua.swig
@@ -9,13 +9,17 @@
%module lldb
%include <std_string.i>
-%include "./lua/lua-typemaps.swig"
-%include "./macros.swig"
-%include "./headers.swig"
+%include "lua-typemaps.swig"
+%include "macros.swig"
+%include "headers.swig"
%{
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "../bindings/lua/lua-swigsafecast.swig"
using namespace lldb_private;
using namespace lldb;
%}
-%include "./interfaces.swig"
+%include "interfaces.swig"
+%include "lua-wrapper.swig"
diff --git a/contrib/llvm-project/lldb/bindings/macros.swig b/contrib/llvm-project/lldb/bindings/macros.swig
index 0387f27f3cb9..6793a11c5bd9 100644
--- a/contrib/llvm-project/lldb/bindings/macros.swig
+++ b/contrib/llvm-project/lldb/bindings/macros.swig
@@ -1,6 +1,5 @@
%define STRING_EXTENSION_LEVEL(Class, Level)
%extend {
- %nothreadallow;
std::string lldb:: ## Class ## ::__str__(){
lldb::SBStream stream;
$self->GetDescription (stream, Level);
@@ -11,13 +10,11 @@
}
return std::string(desc, desc_len);
}
- %clearnothreadallow;
}
%enddef
%define STRING_EXTENSION(Class)
%extend {
- %nothreadallow;
std::string lldb:: ## Class ## ::__str__(){
lldb::SBStream stream;
$self->GetDescription (stream);
@@ -28,6 +25,5 @@
}
return std::string(desc, desc_len);
}
- %clearnothreadallow;
}
%enddef
diff --git a/contrib/llvm-project/lldb/bindings/python/python-extensions.swig b/contrib/llvm-project/lldb/bindings/python/python-extensions.swig
index 0b23fdd40006..b98b0d458f0c 100644
--- a/contrib/llvm-project/lldb/bindings/python/python-extensions.swig
+++ b/contrib/llvm-project/lldb/bindings/python/python-extensions.swig
@@ -290,6 +290,7 @@ class declaration(object):
self.col = col
class value_iter(object):
+ '''Allows iterating over the children of an :py:class:`SBValue`.'''
def __iter__(self):
return self
@@ -311,19 +312,19 @@ class value_iter(object):
self.length = self.sbvalue.GetNumChildren()
class value(object):
- '''A class designed to wrap lldb.SBValue() objects so the resulting object
- can be used as a variable would be in code. So if you have a Point structure
- variable in your code in the current frame named "pt", you can initialize an instance
- of this class with it:
-
- pt = lldb.value(lldb.frame.FindVariable("pt"))
- print pt
- print pt.x
- print pt.y
-
- pt = lldb.value(lldb.frame.FindVariable("rectangle_array"))
- print rectangle_array[12]
- print rectangle_array[5].origin.x'''
+ '''Wraps :py:class:`SBValue` objects so the resulting object can be used as a variable would be in code.
+
+ So if you have a Point structure variable in your code in the current frame named "pt",
+ you can initialize an instance of this class with it: ::
+
+ pt = lldb.value(lldb.frame.FindVariable("pt"))
+ print pt
+ print pt.x
+ print pt.y
+
+ pt = lldb.value(lldb.frame.FindVariable("rectangle_array"))
+ print rectangle_array[12]
+ print rectangle_array[5].origin.x'''
def __init__(self, sbvalue):
self.sbvalue = sbvalue
diff --git a/contrib/llvm-project/lldb/bindings/python/python-swigsafecast.swig b/contrib/llvm-project/lldb/bindings/python/python-swigsafecast.swig
index d5cafbfa67cb..091fc29b1057 100644
--- a/contrib/llvm-project/lldb/bindings/python/python-swigsafecast.swig
+++ b/contrib/llvm-project/lldb/bindings/python/python-swigsafecast.swig
@@ -152,3 +152,10 @@ SBTypeToSWIGWrapper (lldb::SBSymbolContext* sym_ctx_sb)
{
return SWIG_NewPointerObj((void *) sym_ctx_sb, SWIGTYPE_p_lldb__SBSymbolContext, 0);
}
+
+template <>
+PyObject*
+SBTypeToSWIGWrapper (lldb::SBStream* stream_sb)
+{
+ return SWIG_NewPointerObj((void *) stream_sb, SWIGTYPE_p_lldb__SBStream, 0);
+}
diff --git a/contrib/llvm-project/lldb/bindings/python/python-typemaps.h b/contrib/llvm-project/lldb/bindings/python/python-typemaps.h
new file mode 100644
index 000000000000..b45352ad6295
--- /dev/null
+++ b/contrib/llvm-project/lldb/bindings/python/python-typemaps.h
@@ -0,0 +1,17 @@
+#ifndef LLDB_BINDINGS_PYTHON_PYTHON_TYPEMAPS_H
+#define LLDB_BINDINGS_PYTHON_PYTHON_TYPEMAPS_H
+
+// Defined here instead of a .swig file because SWIG 2 doesn't support
+// explicit deleted functions.
+struct Py_buffer_RAII {
+ Py_buffer buffer = {};
+ Py_buffer_RAII(){};
+ Py_buffer &operator=(const Py_buffer_RAII &) = delete;
+ Py_buffer_RAII(const Py_buffer_RAII &) = delete;
+ ~Py_buffer_RAII() {
+ if (buffer.obj)
+ PyBuffer_Release(&buffer);
+ }
+};
+
+#endif // LLDB_BINDINGS_PYTHON_PYTHON_TYPEMAPS_H
diff --git a/contrib/llvm-project/lldb/bindings/python/python-typemaps.swig b/contrib/llvm-project/lldb/bindings/python/python-typemaps.swig
index c08aeab71f78..b1ace4ff3b1e 100644
--- a/contrib/llvm-project/lldb/bindings/python/python-typemaps.swig
+++ b/contrib/llvm-project/lldb/bindings/python/python-typemaps.swig
@@ -1,5 +1,11 @@
/* Typemap definitions, to allow SWIG to properly handle 'char**' data types. */
+%inline %{
+
+#include "../bindings/python/python-typemaps.h"
+
+%}
+
%typemap(in) char ** {
/* Check if is a list */
if (PythonList::Check($input)) {
@@ -61,7 +67,7 @@
%typemap(in) lldb::tid_t {
PythonObject obj = Retain<PythonObject>($input);
- lldb::tid_t value = unwrapOrSetPythonException(As<unsigned long long>(obj));
+ lldb::tid_t value = unwrapOrSetPythonException(As<unsigned long long>(obj));
if (PyErr_Occurred())
return nullptr;
$1 = value;
@@ -476,21 +482,6 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
}
}
-%inline %{
-
-struct Py_buffer_RAII {
- Py_buffer buffer = {};
- Py_buffer_RAII() {};
- Py_buffer &operator=(const Py_buffer_RAII &) = delete;
- Py_buffer_RAII(const Py_buffer_RAII &) = delete;
- ~Py_buffer_RAII() {
- if (buffer.obj)
- PyBuffer_Release(&buffer);
- }
-};
-
-%}
-
// These two pybuffer macros are copied out of swig/Lib/python/pybuffer.i,
// and fixed so they will not crash if PyObject_GetBuffer fails.
// https://github.com/swig/swig/issues/1640
diff --git a/contrib/llvm-project/lldb/bindings/python/python-wrapper.swig b/contrib/llvm-project/lldb/bindings/python/python-wrapper.swig
index f9e89373fe25..443ddfb8dd20 100644
--- a/contrib/llvm-project/lldb/bindings/python/python-wrapper.swig
+++ b/contrib/llvm-project/lldb/bindings/python/python-wrapper.swig
@@ -271,9 +271,6 @@ LLDBSwigPythonCreateScriptedThreadPlan
if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
Py_RETURN_NONE;
- // I do not want the SBThreadPlan to be deallocated when going out of scope because python
- // has ownership of it and will manage memory for this object by itself
- lldb::SBThreadPlan *tp_value = new lldb::SBThreadPlan(thread_plan_sp);
PyErr_Cleaner py_err_cleaner(true);
@@ -286,7 +283,10 @@ LLDBSwigPythonCreateScriptedThreadPlan
return nullptr;
}
- PythonObject tp_arg(PyRefType::Owned, SBTypeToSWIGWrapper(tp_value));
+ // I do not want the SBThreadPlan to be deallocated when going out of scope
+ // because python has ownership of it and will manage memory for this
+ // object by itself
+ PythonObject tp_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBThreadPlan(thread_plan_sp)));
if (!tp_arg.IsAllocated())
Py_RETURN_NONE;
@@ -312,8 +312,7 @@ LLDBSwigPythonCreateScriptedThreadPlan
}
result = pfunc(tp_arg, dict);
} else if (arg_info.get().max_positional_args >= 3) {
- lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl);
- PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value));
+ PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBStructuredData(args_impl)));
result = pfunc(tp_arg, args_arg, dict);
} else {
error_string.assign("wrong number of arguments in __init__, should be 2 or 3 (not including self)");
@@ -469,6 +468,127 @@ LLDBSwigPythonCallBreakpointResolver
return ret_val;
}
+SWIGEXPORT void *
+LLDBSwigPythonCreateScriptedStopHook
+(
+ lldb::TargetSP target_sp,
+ const char *python_class_name,
+ const char *session_dictionary_name,
+ lldb_private::StructuredDataImpl *args_impl,
+ Status &error
+)
+{
+ if (python_class_name == NULL || python_class_name[0] == '\0') {
+ error.SetErrorString("Empty class name.");
+ Py_RETURN_NONE;
+ }
+ if (!session_dictionary_name) {
+ error.SetErrorString("No session dictionary");
+ Py_RETURN_NONE;
+ }
+
+ PyErr_Cleaner py_err_cleaner(true);
+
+ auto dict =
+ PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc =
+ PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_class_name, dict);
+
+ if (!pfunc.IsAllocated()) {
+ error.SetErrorStringWithFormat("Could not find class: %s.",
+ python_class_name);
+ return nullptr;
+ }
+
+ lldb::SBTarget *target_val
+ = new lldb::SBTarget(target_sp);
+
+ PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(target_val));
+
+ lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl);
+ PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value));
+
+ PythonObject result = pfunc(target_arg, args_arg, dict);
+
+ if (result.IsAllocated())
+ {
+ // Check that the handle_stop callback is defined:
+ auto callback_func = result.ResolveName<PythonCallable>("handle_stop");
+ if (callback_func.IsAllocated()) {
+ if (auto args_info = callback_func.GetArgInfo()) {
+ size_t num_args = (*args_info).max_positional_args;
+ if (num_args != 2) {
+ error.SetErrorStringWithFormat("Wrong number of args for "
+ "handle_stop callback, should be 2 (excluding self), got: %zu",
+ num_args);
+ Py_RETURN_NONE;
+ } else
+ return result.release();
+ } else {
+ error.SetErrorString("Couldn't get num arguments for handle_stop "
+ "callback.");
+ Py_RETURN_NONE;
+ }
+ return result.release();
+ }
+ else {
+ error.SetErrorStringWithFormat("Class \"%s\" is missing the required "
+ "handle_stop callback.",
+ python_class_name);
+ result.release();
+ }
+ }
+ Py_RETURN_NONE;
+}
+
+SWIGEXPORT bool
+LLDBSwigPythonStopHookCallHandleStop
+(
+ void *implementor,
+ lldb::ExecutionContextRefSP exc_ctx_sp,
+ lldb::StreamSP stream
+)
+{
+ // handle_stop will return a bool with the meaning "should_stop"...
+ // If you return nothing we'll assume we are going to stop.
+ // Also any errors should return true, since we should stop on error.
+
+ PyErr_Cleaner py_err_cleaner(false);
+ PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
+ auto pfunc = self.ResolveName<PythonCallable>("handle_stop");
+
+ if (!pfunc.IsAllocated())
+ return true;
+
+ PythonObject result;
+ lldb::SBExecutionContext sb_exc_ctx(exc_ctx_sp);
+ PythonObject exc_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_exc_ctx));
+ lldb::SBStream sb_stream;
+ PythonObject sb_stream_arg(PyRefType::Owned,
+ SBTypeToSWIGWrapper(sb_stream));
+ result = pfunc(exc_ctx_arg, sb_stream_arg);
+
+ if (PyErr_Occurred())
+ {
+ stream->PutCString("Python error occurred handling stop-hook.");
+ PyErr_Print();
+ PyErr_Clear();
+ return true;
+ }
+
+ // Now add the result to the output stream. SBStream only
+ // makes an internally help StreamString which I can't interpose, so I
+ // have to copy it over here.
+ stream->PutCString(sb_stream.GetData());
+
+ if (result.get() == Py_False)
+ return false;
+ else
+ return true;
+}
+
// wrapper that calls an optional instance member of an object taking no arguments
static PyObject*
LLDBSwigPython_CallOptionalMember
diff --git a/contrib/llvm-project/lldb/bindings/python.swig b/contrib/llvm-project/lldb/bindings/python/python.swig
index 5b1269878dac..9dc4ab87a4bd 100644
--- a/contrib/llvm-project/lldb/bindings/python.swig
+++ b/contrib/llvm-project/lldb/bindings/python/python.swig
@@ -12,23 +12,27 @@
Some of the important classes are described here:
-o SBTarget: Represents the target program running under the debugger.
-o SBProcess: Represents the process associated with the target program.
-o SBThread: Represents a thread of execution. SBProcess contains SBThread(s).
-o SBFrame: Represents one of the stack frames associated with a thread. SBThread
- contains SBFrame(s).
-o SBSymbolContext: A container that stores various debugger related info.
-o SBValue: Represents the value of a variable, a register, or an expression.
-o SBModule: Represents an executable image and its associated object and symbol
- files. SBTarget contains SBModule(s).
-o SBBreakpoint: Represents a logical breakpoint and its associated settings.
- SBTarget contains SBBreakpoint(s).
-o SBSymbol: Represents the symbol possibly associated with a stack frame.
-o SBCompileUnit: Represents a compilation unit, or compiled source file.
-o SBFunction: Represents a generic function, which can be inlined or not.
-o SBBlock: Represents a lexical block. SBFunction contains SBBlock(s).
-o SBLineEntry: Specifies an association with a contiguous range of instructions
- and a source file location. SBCompileUnit contains SBLineEntry(s)."
+* :py:class:`SBTarget`: Represents the target program running under the debugger.
+* :py:class:`SBProcess`: Represents the process associated with the target program.
+* :py:class:`SBThread`: Represents a thread of execution. :py:class:`SBProcess` contains SBThreads.
+* :py:class:`SBFrame`: Represents one of the stack frames associated with a thread. :py:class:`SBThread`
+ contains SBFrame(s).
+* :py:class:`SBSymbolContext`: A container that stores various debugger related info.
+* :py:class:`SBValue`: Represents the value of a variable, a register, or an expression.
+* :py:class:`SBModule`: Represents an executable image and its associated object and symbol
+ files. :py:class:`SBTarget` contains SBModule.
+* :py:class:`SBBreakpoint`: Represents a logical breakpoint and its associated settings.
+ :py:class:`SBTarget` contains SBBreakpoints.
+* :py:class:`SBSymbol`: Represents the symbol possibly associated with a stack frame.
+* :py:class:`SBCompileUnit`: Represents a compilation unit, or compiled source file.
+* :py:class:`SBFunction`: Represents a generic function, which can be inlined or not.
+* :py:class:`SBBlock`: Represents a lexical block. :py:class:`SBFunction` contains SBBlocks.
+* :py:class:`SBLineEntry`: Specifies an association with a contiguous range of instructions
+ and a source file location. :py:class:`SBCompileUnit` contains SBLineEntry.
+
+The different enums in the `lldb` module are described in :doc:`python_api_enums`.
+
+"
%enddef
/*
@@ -111,9 +115,9 @@ def lldb_iter(obj, getsize, getelem):
%}
%include <std_string.i>
-%include "./python/python-typemaps.swig"
-%include "./macros.swig"
-%include "./headers.swig"
+%include "python-typemaps.swig"
+%include "macros.swig"
+%include "headers.swig"
%{
#include "../source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h"
@@ -123,9 +127,9 @@ using namespace lldb_private::python;
using namespace lldb;
%}
-%include "./interfaces.swig"
-%include "./python/python-extensions.swig"
-%include "./python/python-wrapper.swig"
+%include "interfaces.swig"
+%include "python-extensions.swig"
+%include "python-wrapper.swig"
%pythoncode%{
_initialize = True
diff --git a/contrib/llvm-project/lldb/docs/_lldb/__init__.py b/contrib/llvm-project/lldb/docs/_lldb/__init__.py
new file mode 100644
index 000000000000..084252e46e5d
--- /dev/null
+++ b/contrib/llvm-project/lldb/docs/_lldb/__init__.py
@@ -0,0 +1,9 @@
+from unittest.mock import Mock
+import sys
+import types
+
+# This package acts as a mock implementation of the native _lldb module so
+# that generating the LLDB documentation doesn't actually require building all
+# of LLDB.
+module_name = '_lldb'
+sys.modules[module_name] = Mock()
diff --git a/contrib/llvm-project/lldb/docs/design/overview.rst b/contrib/llvm-project/lldb/docs/design/overview.rst
new file mode 100644
index 000000000000..72eac56d6c3e
--- /dev/null
+++ b/contrib/llvm-project/lldb/docs/design/overview.rst
@@ -0,0 +1,192 @@
+Overview
+========
+
+LLDB is a large and complex codebase. This section will help you become more
+familiar with the pieces that make up LLDB and give a general overview of the
+general architecture.
+
+LLDB has many code groupings that makeup the source base:
+
+.. contents::
+ :local:
+
+API
+---
+
+The API folder contains the public interface to LLDB.
+
+We are currently vending a C++ API. In order to be able to add methods to this
+API and allow people to link to our classes, we have certain rules that we must
+follow:
+
+- Classes can't inherit from any other classes.
+- Classes can't contain virtual methods.
+- Classes should be compatible with script bridging utilities like swig.
+- Classes should be lightweight and be backed by a single member. Pointers (or
+ shared pointers) are the preferred choice since they allow changing the
+ contents of the backend without affecting the public object layout.
+- The interface should be as minimal as possible in order to give a complete
+ API.
+
+By adhering to these rules we should be able to continue to vend a C++ API, and
+make changes to the API as any additional methods added to these classes will
+just be a dynamic loader lookup and they won't affect the class layout (since
+they aren't virtual methods, and no members can be added to the class).
+
+Breakpoint
+----------
+
+A collection of classes that implement our breakpoint classes. Breakpoints are
+resolved symbolically and always continue to resolve themselves as your program
+runs. Whether settings breakpoints by file and line, by symbol name, by symbol
+regular expression, or by address, breakpoints will keep trying to resolve new
+locations each time shared libraries are loaded. Breakpoints will of course
+unresolve themselves when shared libraries are unloaded. Breakpoints can also
+be scoped to be set only in a specific shared library. By default, breakpoints
+can be set in any shared library and will continue to attempt to be resolved
+with each shared library load.
+
+Breakpoint options can be set on the breakpoint, or on the individual
+locations. This allows flexibility when dealing with breakpoints and allows us
+to do what the user wants.
+
+Commands
+--------
+
+The command source files represent objects that implement the functionality for
+all textual commands available in our command line interface.
+
+Every command is backed by a ``lldb_private::CommandObject`` or
+``lldb_private::CommandObjectMultiword`` object.
+
+``lldb_private::CommandObjectMultiword`` are commands that have subcommands and
+allow command line commands to be logically grouped into a hierarchy.
+
+``lldb_private::CommandObject`` command line commands are the objects that
+implement the functionality of the command. They can optionally define options
+for themselves, as well as group those options into logical groups that can go
+together. The help system is tied into these objects and can extract the syntax
+and option groupings to display appropriate help for each command.
+
+Core
+----
+
+The Core source files contain basic functionality that is required in the
+debugger as well as the class represeting the debugger it self (Debugger). A
+wide variety of classes are implemented:
+
+- Address (section offset addressing)
+- AddressRange
+- Broadcaster / Event / Listener
+- Communication classes that use Connection objects
+- Mangled names
+- Source manager
+- Value objects
+
+Dataformatters
+--------------
+
+A collection of classes that implement the data formatters subsystem.
+
+Data formatters provide a set of user-tweakable hooks in the ValueObjects world
+that allow to customize presentation aspects of variables. While users interact
+with formatters mostly through the type command, inside LLDB there are a few
+layers to the implementation: DataVisualization at the highest end of the
+spectrum, backed by classes implementing individual formatters, matching rules,
+etc.
+
+For a general user-level introduction to data formatters, you can look here.
+
+More details on the architecture are to be found here.
+
+Expression
+----------
+
+Expression parsing files cover everything from evaluating DWARF expressions, to
+evaluating expressions using Clang.
+
+The DWARF expression parser has been heavily modified to support type
+promotion, new opcodes needed for evaluating expressions with symbolic variable
+references (expression local variables, program variables), and other operators
+required by typical expressions such as assign, address of, float/double/long
+double floating point values, casting, and more. The DWARF expression parser
+uses a stack of lldb_private::Value objects. These objects know how to do the
+standard C type promotion, and allow for symbolic references to variables in
+the program and in the LLDB process (expression local and expression global
+variables).
+
+The expression parser uses a full instance of the Clang compiler in order to
+accurately evaluate expressions. Hooks have been put into Clang so that the
+compiler knows to ask about identifiers it doesn't know about. Once expressions
+have be compiled into an AST, we can then traverse this AST and either generate
+a DWARF expression that contains simple opcodes that can be quickly
+re-evaluated each time an expression needs to be evaluated, or JIT'ed up into
+code that can be run on the process being debugged.
+
+Host
+----
+
+LLDB tries to abstract itself from the host upon which it is currently running
+by providing a host abstraction layer. This layer includes functionality, whose
+implementation varies wildly from host to host.
+
+Host functionality includes abstraction layers for:
+
+- Information about the host system (triple, list of running processes, etc.)
+- Launching processes
+- Various OS primitives like pipes and sockets
+
+It also includes the base classes of the NativeProcess/Thread hierarchy, which
+is used by lldb-server.
+
+Interpreter
+-----------
+
+The interpreter classes are the classes responsible for being the base classes
+needed for each command object, and is responsible for tracking and running
+command line commands.
+
+Symbol
+------
+
+Symbol classes involve everything needed in order to parse object files and
+debug symbols. All the needed classes for compilation units (code and debug
+info for a source file), functions, lexical blocks within functions, inlined
+functions, types, declaration locations, and variables are in this section.
+
+Target
+------
+
+Classes that are related to a debug target include:
+
+- Target
+- Process
+- Thread
+- Stack frames
+- Stack frame registers
+- ABI for function calling in process being debugged
+- Execution context batons
+
+Utility
+-------
+
+This module contains the lowest layers of LLDB. A lot of these classes don't
+really have anything to do with debugging -- they are just there because the
+higher layers of the debugger use these clasess to implement their
+functionality. Others are data structures used in many other parts of the
+debugger (TraceOptions). Most of the functionality in this module could be
+useful in an application that is not a debugger; however, providing a general
+purpose C++ library is an explicit non-goal of this module.
+
+This module provides following functionality:
+
+- Abstract path manipulation (FileSpec)
+- Architecture specification
+- Data buffers (DataBuffer, DataEncoder, DataExtractor)
+- Logging
+- Structured data manipulation (JSON)
+- Streams
+- Timers
+
+For historic reasons, some of this functionality overlaps that which is
+provided by the LLVM support library.
diff --git a/contrib/llvm-project/lldb/docs/design/reproducers.rst b/contrib/llvm-project/lldb/docs/design/reproducers.rst
new file mode 100644
index 000000000000..d8ad3dd7866d
--- /dev/null
+++ b/contrib/llvm-project/lldb/docs/design/reproducers.rst
@@ -0,0 +1,212 @@
+Reproducers
+===========
+
+As unbelievable as it may sound, the debugger has bugs. These bugs might
+manifest themselves as errors, missing results or even a crash. Quite often
+these bugs don't reproduce in simple, isolated scenarios. The debugger deals
+with a lot of moving parts and subtle differences can easily add up.
+
+Reproducers in LLDB improve the experience for both the users encountering bugs
+and the developers working on resolving them. The general idea consists of
+*capturing* all the information necessary to later *replay* a debug session
+while debugging the debugger.
+
+.. contents::
+ :local:
+
+Usage
+-----
+
+Reproducers are a generic concept in LLDB and are not inherently coupled with
+the command line driver. The functionality can be used for anything that uses
+the SB API and the driver is just one example. However, because it's probably
+the most common way users interact with lldb, that's the workflow described in
+this section.
+
+Capture
+```````
+
+Until reproducer capture is enabled by default, you need to launch LLDB in
+capture mode. For the command line driver, this means passing ``--capture``.
+You cannot enable reproducer capture from within LLDB, as this would be too
+late to capture initialization of the debugger.
+
+.. code-block:: bash
+
+ > lldb --capture
+
+In capture mode, LLDB will keep track of all the information it needs to replay
+the current debug session. Most data is captured lazily to limit the impact on
+performance. To create the reproducer, use the ``reproducer generate``
+sub-command. It's always possible to check the status of the reproducers with
+the ``reproducer status`` sub-command. Note that generating the reproducer
+terminates the debug session.
+
+.. code-block:: none
+
+ (lldb) reproducer status
+ Reproducer is in capture mode.
+ (lldb) reproducer generate
+ Reproducer written to '/path/to/reproducer'
+ Please have a look at the directory to assess if you're willing to share the contained information.
+
+
+The resulting reproducer is a directory. It was a conscious decision to not
+compress and archive it automatically. The reproducer can contain potentially
+sensitive information like object and symbol files, their paths on disk, debug
+information, memory excerpts of the inferior process, etc.
+
+Replay
+``````
+
+It is strongly recommended to replay the reproducer locally to ensure it
+actually reproduces the expected behavior. If the reproducer doesn't behave
+correctly locally, it means there's a bug in the reproducer implementation that
+should be addressed.
+
+To replay a reproducer, simply pass its path to LLDB through the ``--replay``
+flag. It is unnecessary to pass any other command line flags. The flags that
+were passed to LLDB during capture are already part of the reproducer.
+
+.. code-block:: bash
+
+ > lldb --replay /path/to/reproducer
+
+
+During replay LLDB will behave similar to batch mode. The session should be
+identical to the recorded debug session. The only expected differences are that
+the binary being debugged doesn't actually run during replay. That means that
+you won't see any of its side effects, like things being printed to the
+terminal. Another expected difference is the behavior of the ``reproducer
+generate`` command, which becomes a NOOP during replay.
+
+Augmenting a Bug Report with a Reproducer
+`````````````````````````````````````````
+
+A reproducer can significantly improve a bug report, but it in itself is not
+sufficient. Always describe the expected and unexpected behavior. Just like the
+debugger can have bugs, the reproducer can have bugs too.
+
+
+Design
+------
+
+
+Replay
+``````
+
+Reproducers support two replay modes. The main and most common mode is active
+replay. It's called active, because it's LLDB that is driving replay by calling
+the captured SB API functions one after each other. The second mode is passive
+replay. In this mode, LLDB sits idle until an SB API function is called, for
+example from Python, and then replays just this individual call.
+
+Active Replay
+^^^^^^^^^^^^^
+
+No matter how a reproducer was captured, they can always be replayed with the
+command line driver. When a reproducer is passed with the ``--replay`` flag, the
+driver short-circuits and passes off control to the reproducer infrastructure,
+effectively bypassing its normal operation. This works because the driver is
+implemented using the SB API and is therefore nothing more than a sequence of
+SB API calls.
+
+Replay is driven by the ``Registry::Replay``. As long as there's data in the
+buffer holding the API data, the next SB API function call is deserialized.
+Once the function is known, the registry can retrieve its signature, and use
+that to deserialize its arguments. The function can then be invoked, most
+commonly through the synthesized default replayer, or potentially using a
+custom defined replay function. This process continues, until more data is
+available or a replay error is encountered.
+
+During replay only a function's side effects matter. The result returned by the
+replayed function is ignored because it cannot be observed beyond the driver.
+This is sound, because anything that is passed into a subsequent API call will
+have been serialized as an input argument. This also works for SB API objects
+because the reproducers know about every object that has crossed the API
+boundary, which is true by definition for object return values.
+
+
+Passive Replay
+^^^^^^^^^^^^^^
+
+Passive replay exists to support running the API test suite against a
+reproducer. The API test suite is written in Python and tests the debugger by
+calling into its API from Python. To make this work, the API must transparently
+replay itself when called. This is what makes passive replay different from
+driver replay, where it is lldb itself that's driving replay. For passive
+replay, the driving factor is external.
+
+In order to replay API calls, the reproducers need a way to intercept them.
+Every API call is already instrumented with an ``LLDB_RECORD_*`` macro that
+captures its input arguments. Furthermore, it also contains the necessary logic
+to detect which calls cross the API boundary and should be intercepted. We were
+able to reuse all of this to implement passive replay.
+
+During passive replay is enabled, nothing happens until an SB API is called.
+Inside that API function, the macro detects whether this call should be
+replayed (i.e. crossed the API boundary). If the answer is yes, the next
+function is deserialized from the SB API data and compared to the current
+function. If the signature matches, we deserialize its input arguments and
+reinvoke the current function with the deserialized arguments. We don't need to
+do anything special to prevent us from recursively calling the replayed version
+again, as the API boundary crossing logic knows that we're still behind the API
+boundary when we re-invoked the current function.
+
+Another big difference with driver replay is the return value. While this
+didn't matter for driver replay, it's key for passive replay, because that's
+what gets checked by the test suite. Luckily, the ``LLDB_RECORD_*`` macros
+contained sufficient type information to derive the result type.
+
+Testing
+-------
+
+Reproducers are tested in the following ways:
+
+ - Unit tests to cover the reproducer infrastructure. There are tests for the
+ provider, loader and for the reproducer instrumentation.
+ - Feature specific end-to-end test cases in the ``test/Shell/Reproducer``
+ directory. These tests serve as integration and regression tests for the
+ reproducers infrastructure, as well as doing some sanity checking for basic
+ debugger functionality.
+ - The API and shell tests can be run against a replayed reproducer. The
+ ``check-lldb-reproducers`` target will run the API and shell test suite
+ twice: first running the test normally while capturing a reproducer and then
+ a second time using the replayed session as the test input. For the shell
+ tests this use a little shim (``lldb-repro``) that uses the arguments and
+ current working directory to transparently generate or replay a reproducer.
+ For the API tests an extra argument with the reproducer path is passed to
+ ``dotest.py`` which initializes the debugger in the appropriate mode.
+ Certain tests do not fit this paradigm (for example test that check the
+ output of the binary being debugged) and are skipped by marking them as
+ unsupported by adding ``UNSUPPORTED: lldb-repro`` to the top of the shell
+ test or adding the ``skipIfReproducer`` decorator for the API tests.
+
+Additional testing is possible:
+
+ - It's possible to unconditionally capture reproducers while running the
+ entire test suite by setting the ``LLDB_CAPTURE_REPRODUCER`` environment
+ variable. Assuming no bugs in reproducers, this can also help to reproduce
+ and investigate test failures.
+
+Knows Issues
+------------
+
+The reproducers are still a work in progress. Here's a non-exhaustive list of
+outstanding work, limitations and known issues.
+
+ - The VFS cannot deal with more than one current working directory. Changing
+ the current working directory during the debug session will break relative
+ paths.
+ - Not all SB APIs are properly instrumented. We need customer serialization
+ for APIs that take buffers and lengths.
+ - We leak memory during replay because the reproducer doesn't capture the end
+ of an object's life time. We need to add instrumentation to the destructor
+ of SB API objects.
+ - The reproducer includes every file opened by LLDB. This is overkill. For
+ example we do not need to capture source files for code listings. There's
+ currently no way to say that some file shouldn't be included in the
+ reproducer.
+ - We do not yet automatically generate a reproducer on a crash. The reason is
+ that generating the reproducer is too expensive to do in a signal handler.
+ We should re-invoke lldb after a crash and do the heavy lifting.
diff --git a/contrib/llvm-project/lldb/docs/design/sbapi.rst b/contrib/llvm-project/lldb/docs/design/sbapi.rst
new file mode 100644
index 000000000000..676509bbd99e
--- /dev/null
+++ b/contrib/llvm-project/lldb/docs/design/sbapi.rst
@@ -0,0 +1,95 @@
+Scripting Bridge API
+====================
+
+The SB APIs constitute the stable C++ API that lldb presents to external
+clients, and which get processed by SWIG to produce the Python bindings to
+lldb. As such it is important that they not suffer from the binary
+incompatibilities that C++ is so susceptible to. We've established a few rules
+to ensure that this happens.
+
+The classes in the SB API's are all called SB<SomeName>, where SomeName is in
+CamelCase starting with an upper case letter. The method names are all
+CamelCase with initial capital letter as well.
+
+All the SB API classes are non-virtual, single inheritance classes. They should
+only include SBDefines.h or other SB headers as needed. There should be no
+inlined method implementations in the header files, they should all be in the
+implementation files. And there should be no direct ivar access.
+
+You also need to choose the ivars for the class with care, since you can't add
+or remove ivars without breaking binary compatibility. In some cases, the SB
+class is a thin wrapper around an internal lldb_private object. In that case,
+the class can have a single ivar, which is either a pointer, shared_ptr or
+unique_ptr to the object in the lldb_private API. All the lldb_private classes
+that get used this way are declared as opaque classes in lldb_forward.h, which
+is included in SBDefines.h. So if you need an SB class to wrap an lldb_private
+class that isn't in lldb_forward.h, add it there rather than making a direct
+opaque declaration in the SB classes .h file.
+
+If the SB Class needs some state of its own, as well as the backing object,
+don't include that as a direct ivar in the SB Class. Instead, make an Impl
+class in the SB's .cpp file, and then make the SB object hold a shared or
+unique pointer to the Impl object. The theory behind this is that if you need
+more state in the SB object, those needs are likely to change over time, and
+this way the Impl class can pick up members without changing the size of the
+object. An example of this is the SBValue class. Please note that you should
+not put this Impl class in the lldb namespace. Failure to do so leads to
+leakage of weak-linked symbols in the SBAPI.
+
+In order to fit into the Python API's, we need to be able to default construct
+all the SB objects. Since the ivars of the classes are all pointers of one sort
+or other, this can easily be done, but it means all the methods must be
+prepared to handle their opaque implementation pointer being empty, and doing
+something reasonable. We also always have an "IsValid" method on all the SB
+classes to report whether the object is empty or not.
+
+Another piece of the SB API infrastructure is the Python (or other script
+interpreter) customization. SWIG allows you to add property access, iterators
+and documentation to classes, but to do that you have to use a Swig interface
+file in place of the .h file. Those files have a different format than a
+straight C++ header file. These files are called SB<ClassName>.i, and live in
+"scripts/interface". They are constructed by starting with the associated .h
+file, and adding documentation and the Python decorations, etc. We do this in a
+decidedly low-tech way, by maintaining the two files in parallel. That
+simplifies the build process, but it does mean that if you add a method to the
+C++ API's for an SB class, you have to copy the interface to the .i file.
+
+API Instrumentation
+-------------------
+
+The reproducer infrastructure requires API methods to be instrumented so that
+they can be captured and replayed. Instrumentation consists of two macros,
+``LLDB_REGISTER`` and ``LLDB_RECORD``. Both can be automatically generated with
+the ``lldb-instr`` utility.
+
+To add instrumentation for a given file, pass it to the ``lldb-instr`` tool.
+Like other clang-based tools it requires a compilation database
+(``compile_commands.json``) to be present in the current working directory.
+
+::
+
+ ./bin/lldb-instr /path/to/lldb/source/API/SBDebugger.cpp
+
+
+The tool will automatically insert ``LLDB_RECORD`` macros inline, however you
+will need to run ``clang-format`` over the processed file, as the tool
+(intentionally) makes no attempt to get that right.
+
+The ``LLDB_REGISTER`` macros are printed to standard out between curly braces.
+You'll have to copy-paste those into the corresponding ``RegisterMethods``
+function in the implementation file. This function is fully specialized in the
+corresponding type.
+
+::
+
+ template <> void RegisterMethods<SBDebugger>(Registry &R) {
+ ...
+ }
+
+
+When adding a new class, you'll also have to add a call to ``RegisterMethods``
+in the ``SBRegistry`` constructor.
+
+The tool can be used incrementally. However, it will ignore existing macros
+even if their signature is wrong. It will only generate a ``LLDB_REGISTER`` if
+it emitted a corresponding ``LLDB_RECORD`` macro.
diff --git a/contrib/llvm-project/lldb/docs/design/structureddataplugins.md b/contrib/llvm-project/lldb/docs/design/structureddataplugins.md
new file mode 100644
index 000000000000..79c410800b2c
--- /dev/null
+++ b/contrib/llvm-project/lldb/docs/design/structureddataplugins.md
@@ -0,0 +1,442 @@
+# Structured Data Plugins
+
+This document describes an infrastructural feature called Structured Data
+plugins. See the DarwinLog documentation for a description of one such plugin
+that makes use of this feature.
+
+StructuredDataPlugin instances have the following characteristics:
+
+* Each plugin instance is bound to a single Process instance.
+
+* Each StructuredData feature has a type name that identifies the
+ feature. For instance, the type name for the DarwinLog feature is
+ "DarwinLog". This feature type name is used in various places.
+
+* The process monitor reports the list of supported StructuredData
+ features advertised by the process monitor. Process goes through the
+ list of supported feature type names, and asks each known
+ StructuredDataPlugin if it can handle the feature. The first plugin
+ that supports the feature is mapped to that Process instance for
+ that feature. Plugins are only mapped when the process monitor
+ advertises that a feature is supported.
+
+* The feature may send asynchronous messages in StructuredData format
+ to the Process instance. Process instances route the asynchronous
+ structured data messages to the plugin mapped to that feature type,
+ if one exists.
+
+* Plugins can request that the Process instance forward on
+ configuration data to the process monitor if the plugin needs/wants
+ to configure the feature. Plugins may call the new Process method
+
+ ```C++
+ virtual Error
+ ConfigureStructuredData(ConstString type_name,
+ const StructuredData::ObjectSP &config_sp)
+ ```
+
+ where `type_name` is the feature name and `config_sp` points to the
+ configuration structured data, which may be nullptr.
+
+* Plugins for features present in a process are notified when modules
+ are loaded into the Process instance via this StructuredDataPlugin
+ method:
+
+ ```C++
+ virtual void
+ ModulesDidLoad(Process &process, ModuleList &module_list);
+ ```
+
+* Plugins may optionally broadcast their received structured data as
+ an LLDB process-level event via the following new Process call:
+
+ ```C++
+ void
+ BroadcastStructuredData(const StructuredData::ObjectSP &object_sp,
+ const lldb::StructuredDataPluginSP &plugin_sp);
+ ```
+
+ IDE clients might use this feature to receive information about the
+ process as it is running to monitor memory usage, CPU usage, and
+ logging.
+
+ Internally, the event type created is an instance of
+ EventDataStructuredData.
+
+* In the case where a plugin chooses to broadcast a received
+ StructuredData event, the command-line LLDB Debugger instance
+ listens for them. The Debugger instance then gives the plugin an
+ opportunity to display info to either the debugger output or error
+ stream at a time that is safe to write to them. The plugin can
+ choose to display something appropriate regarding the structured
+ data that time.
+
+* Plugins can provide a ProcessLaunchInfo filter method when the
+ plugin is registered. If such a filter method is provided, then
+ when a process is about to be launched for debugging, the filter
+ callback is invoked, given both the launch info and the target. The
+ plugin may then alter the launch info if needed to better support
+ the feature of the plugin.
+
+* The plugin is entirely independent of the type of Process-derived
+ class that it is working with. The only requirements from the
+ process monitor are the following feature-agnostic elements:
+
+ * Provide a way to discover features supported by the process
+ monitor for the current process.
+
+ * Specify the list of supported feature type names to Process.
+ The process monitor does this by calling the following new
+ method on Process:
+
+ ```C++
+ void
+ MapSupportedStructuredDataPlugins(const StructuredData::Array
+ &supported_type_names)
+ ```
+
+ The `supported_type_names` specifies an array of string entries,
+ where each entry specifies the name of a StructuredData feature.
+
+ * Provide a way to forward on configuration data for a feature type
+ to the process monitor. This is the manner by which LLDB can
+ configure a feature, perhaps based on settings or commands from
+ the user. The following virtual method on Process (described
+ earlier) does the job:
+
+ ```C++
+ virtual Error
+ ConfigureStructuredData(ConstString type_name,
+ const StructuredData::ObjectSP &config_sp)
+ ```
+
+ * Listen for asynchronous structured data packets from the process
+ monitor, and forward them on to Process via this new Process
+ member method:
+
+ ```C++
+ bool
+ RouteAsyncStructuredData(const StructuredData::ObjectSP object_sp)
+ ```
+
+* StructuredData producers must send their top-level data as a
+ Dictionary type, with a key called 'type' specifying a string value,
+ where the value is equal to the StructuredData feature/type name
+ previously advertised. Everything else about the content of the
+ dictionary is entirely up to the feature.
+
+* StructuredDataPlugin commands show up under `plugin structured-data
+ plugin-name`.
+
+* StructuredDataPlugin settings show up under
+ `plugin.structured-data.{plugin-name}`.
+
+## StructuredDataDarwinLog feature
+
+The DarwinLog feature supports logging `os_log`*() and `NSLog`() messages
+to the command-line lldb console, as well as making those messages
+available to LLDB clients via the event system. Starting with fall
+2016 OSes, Apple platforms introduce a new fire-hose, stream-style
+logging system where the bulk of the log processing happens on the log
+consumer side. This reduces logging impact on the system when there
+are no consumers, making it cheaper to include logging at all times.
+However, it also increases the work needed on the consumer end when
+log messages are desired.
+
+The debugserver binary has been modified to support collection of
+`os_log`*()/`NSLog`() messages, selection of which messages appear in the
+stream, and fine-grained filtering of what gets passed on to the LLDB
+client. DarwinLog also tracks the activity chain (i.e. `os_activity`()
+hierarchy) in effect at the time the log messages were issued. The
+user is able to configure a number of aspects related to the
+formatting of the log message header fields.
+
+The DarwinLog support is written in a way which should support the
+lldb client side on non-Apple clients talking to an Apple device or
+macOS system; hence, the plugin support is built into all LLDB
+clients, not just those built on an Apple platform.
+
+StructuredDataDarwinLog implements the 'DarwinLog' feature type, and
+the plugin name for it shows up as `darwin-log`.
+
+The user interface to the darwin-log support is via the following:
+
+* `plugin structured-data darwin-log enable` command
+
+ This is the main entry point for enabling the command. It can be
+ set before launching a process or while the process is running.
+ If the user wants to squelch seeing info-level or debug-level
+ messages, which is the default behavior, then the enable command
+ must be made prior to launching the process; otherwise, the
+ info-level and debug-level messages will always show up. Also,
+ there is a similar "echo os_log()/NSLog() messages to target
+ process stderr" mechanism which is properly disabled when enabling
+ the DarwinLog support prior to launch. This cannot be squelched
+ if enabling DarwinLog after launch.
+
+ See the help for this command. There are a number of options
+ to shrink or expand the number of messages that are processed
+ on the remote side and sent over to the client, and other
+ options to control the formatting of messages displayed.
+
+ This command is sticky. Once enabled, it will stay enabled for
+ future process launches.
+
+* `plugin structured-data darwin-log disable` command
+
+ Executing this command disables os_log() capture in the currently
+ running process and signals LLDB to stop attempting to launch
+ new processes with DarwinLog support enabled.
+
+* `settings set
+ plugin.structured-data.darwin-log.enable-on-startup true`
+
+ and
+
+ `settings set
+ plugin.structured-data.darwin-log.auto-enable-options -- `{options}
+
+ When `enable-on-startup` is set to `true`, then LLDB will automatically
+ enable DarwinLog on startup of relevant processes. It will use the
+ content provided in the auto-enable-options settings as the
+ options to pass to the enable command.
+
+ Note the `--` required after auto-enable-command. That is necessary
+ for raw commands like settings set. The `--` will not become part
+ of the options for the enable command.
+
+### Message flow and related performance considerations
+
+`os_log`()-style collection is not free. The more data that must be
+processed, the slower it will be. There are several knobs available
+to the developer to limit how much data goes through the pipe, and how
+much data ultimately goes over the wire to the LLDB client. The
+user's goal should be to ensure he or she only collects as many log
+messages are needed, but no more.
+
+The flow of data looks like the following:
+
+1. Data comes into debugserver from the low-level OS facility that
+ receives log messages. The data that comes through this pipe can
+ be limited or expanded by the `--debug`, `--info` and
+ `--all-processes` options of the `plugin structured-data darwin-log
+ enable` command options. Exclude as many categories as possible
+ here (also the default). The knobs here are very coarse - for
+ example, whether to include `os_log_info()`-level or
+ `os_log_debug()`-level info, or to include callstacks in the log
+ message event data.
+
+2. The debugserver process filters the messages that arrive through a
+ message log filter that may be fully customized by the user. It
+ works similar to a rules-based packet filter: a set of rules are
+ matched against the log message, each rule tried in sequential
+ order. The first rule that matches then either accepts or rejects
+ the message. If the log message does not match any rule, then the
+ message gets the no-match (i.e. fall-through) action. The no-match
+ action defaults to accepting but may be set to reject.
+
+ Filters can be added via the enable command's '`--filter`
+ {filter-spec}' option. Filters are added in order, and multiple
+ `--filter` entries can be provided to the enable command.
+
+ Filters take the following form:
+```
+ {action} {attribute} {op}
+
+ {action} :=
+ accept |
+ reject
+
+ {attribute} :=
+ category | // The log message category
+ subsystem | // The log message subsystem
+ activity | // The child-most activity in force
+ // at the time the message was logged.
+ activity-chain | // The complete activity chain, specified
+ // as {parent-activity}:{child-activity}:
+ // {grandchild-activity}
+ message | // The fully expanded message contents.
+ // Note this one is expensive because it
+ // requires expanding the message. Avoid
+ // this if possible, or add it further
+ // down the filter chain.
+
+ {op} :=
+ match {exact-match-text} |
+ regex {search-regex} // uses C++ std::regex
+ // ECMAScript variant.
+```
+ e.g.
+ `--filter "accept subsystem match com.example.mycompany.myproduct"`
+ `--filter "accept subsystem regex com.example.+"`
+ `--filter "reject category regex spammy-system-[[:digit:]]+"`
+
+3. Messages that are accepted by the log message filter get sent to
+ the lldb client, where they are mapped to the
+ StructuredDataDarwinLog plugin. By default, command-line lldb will
+ issue a Process-level event containing the log message content, and
+ will request the plugin to print the message if the plugin is
+ enabled to do so.
+
+### Log message display
+
+Several settings control aspects of displaying log messages in
+command-line LLDB. See the `enable` command's help for a description
+of these.
+
+
+## StructuredDataDarwinLog feature
+
+The DarwinLog feature supports logging `os_log`*() and `NSLog`() messages
+to the command-line lldb console, as well as making those messages
+available to LLDB clients via the event system. Starting with fall
+2016 OSes, Apple platforms introduce a new fire-hose, stream-style
+logging system where the bulk of the log processing happens on the log
+consumer side. This reduces logging impact on the system when there
+are no consumers, making it cheaper to include logging at all times.
+However, it also increases the work needed on the consumer end when
+log messages are desired.
+
+The debugserver binary has been modified to support collection of
+`os_log`*()/`NSLog`() messages, selection of which messages appear in the
+stream, and fine-grained filtering of what gets passed on to the LLDB
+client. DarwinLog also tracks the activity chain (i.e. `os_activity`()
+hierarchy) in effect at the time the log messages were issued. The
+user is able to configure a number of aspects related to the
+formatting of the log message header fields.
+
+The DarwinLog support is written in a way which should support the
+lldb client side on non-Apple clients talking to an Apple device or
+macOS system; hence, the plugin support is built into all LLDB
+clients, not just those built on an Apple platform.
+
+StructuredDataDarwinLog implements the 'DarwinLog' feature type, and
+the plugin name for it shows up as `darwin-log`.
+
+The user interface to the darwin-log support is via the following:
+
+* `plugin structured-data darwin-log enable` command
+
+ This is the main entry point for enabling the command. It can be
+ set before launching a process or while the process is running.
+ If the user wants to squelch seeing info-level or debug-level
+ messages, which is the default behavior, then the enable command
+ must be made prior to launching the process; otherwise, the
+ info-level and debug-level messages will always show up. Also,
+ there is a similar "echo os_log()/NSLog() messages to target
+ process stderr" mechanism which is properly disabled when enabling
+ the DarwinLog support prior to launch. This cannot be squelched
+ if enabling DarwinLog after launch.
+
+ See the help for this command. There are a number of options
+ to shrink or expand the number of messages that are processed
+ on the remote side and sent over to the client, and other
+ options to control the formatting of messages displayed.
+
+ This command is sticky. Once enabled, it will stay enabled for
+ future process launches.
+
+* `plugin structured-data darwin-log disable` command
+
+ Executing this command disables os_log() capture in the currently
+ running process and signals LLDB to stop attempting to launch
+ new processes with DarwinLog support enabled.
+
+* `settings set
+ plugin.structured-data.darwin-log.enable-on-startup true`
+
+ and
+
+ `settings set
+ plugin.structured-data.darwin-log.auto-enable-options -- `{options}
+
+ When `enable-on-startup` is set to `true`, then LLDB will automatically
+ enable DarwinLog on startup of relevant processes. It will use the
+ content provided in the auto-enable-options settings as the
+ options to pass to the enable command.
+
+ Note the `--` required after auto-enable-command. That is necessary
+ for raw commands like settings set. The `--` will not become part
+ of the options for the enable command.
+
+### Message flow and related performance considerations
+
+`os_log`()-style collection is not free. The more data that must be
+processed, the slower it will be. There are several knobs available
+to the developer to limit how much data goes through the pipe, and how
+much data ultimately goes over the wire to the LLDB client. The
+user's goal should be to ensure he or she only collects as many log
+messages are needed, but no more.
+
+The flow of data looks like the following:
+
+1. Data comes into debugserver from the low-level OS facility that
+ receives log messages. The data that comes through this pipe can
+ be limited or expanded by the `--debug`, `--info` and
+ `--all-processes` options of the `plugin structured-data darwin-log
+ enable` command options. Exclude as many categories as possible
+ here (also the default). The knobs here are very coarse - for
+ example, whether to include `os_log_info()`-level or
+ `os_log_debug()`-level info, or to include callstacks in the log
+ message event data.
+
+2. The debugserver process filters the messages that arrive through a
+ message log filter that may be fully customized by the user. It
+ works similar to a rules-based packet filter: a set of rules are
+ matched against the log message, each rule tried in sequential
+ order. The first rule that matches then either accepts or rejects
+ the message. If the log message does not match any rule, then the
+ message gets the no-match (i.e. fall-through) action. The no-match
+ action defaults to accepting but may be set to reject.
+
+ Filters can be added via the enable command's '`--filter`
+ {filter-spec}' option. Filters are added in order, and multiple
+ `--filter` entries can be provided to the enable command.
+
+ Filters take the following form:
+```
+ {action} {attribute} {op}
+
+ {action} :=
+ accept |
+ reject
+
+ {attribute} :=
+ category | // The log message category
+ subsystem | // The log message subsystem
+ activity | // The child-most activity in force
+ // at the time the message was logged.
+ activity-chain | // The complete activity chain, specified
+ // as {parent-activity}:{child-activity}:
+ // {grandchild-activity}
+ message | // The fully expanded message contents.
+ // Note this one is expensive because it
+ // requires expanding the message. Avoid
+ // this if possible, or add it further
+ // down the filter chain.
+
+ {op} :=
+ match {exact-match-text} |
+ regex {search-regex} // uses C++ std::regex
+ // ECMAScript variant.
+```
+ e.g.
+ `--filter "accept subsystem match com.example.mycompany.myproduct"`
+ `--filter "accept subsystem regex com.example.+"`
+ `--filter "reject category regex spammy-system-[[:digit:]]+"`
+
+3. Messages that are accepted by the log message filter get sent to
+ the lldb client, where they are mapped to the
+ StructuredDataDarwinLog plugin. By default, command-line lldb will
+ issue a Process-level event containing the log message content, and
+ will request the plugin to print the message if the plugin is
+ enabled to do so.
+
+### Log message display
+
+Several settings control aspects of displaying log messages in
+command-line LLDB. See the `enable` command's help for a description
+of these.
+
+
+
diff --git a/contrib/llvm-project/lldb/docs/man/lldb-server.rst b/contrib/llvm-project/lldb/docs/man/lldb-server.rst
new file mode 100644
index 000000000000..a67c00b305f6
--- /dev/null
+++ b/contrib/llvm-project/lldb/docs/man/lldb-server.rst
@@ -0,0 +1,209 @@
+:orphan:
+
+lldb-server -- Server for LLDB Debugging Sessions
+=================================================
+
+.. program:: lldb-server
+
+SYNOPSIS
+--------
+
+| :program:`lldb-server` v[ersion]
+| :program:`lldb-server` g[dbserver] [*options*]
+| :program:`lldb-server` p[latform] [*options*]
+
+DESCRIPTION
+-----------
+
+:program:`lldb-server` provides the server counterpart of the LLVM debugger.
+The server runs and monitors the debugged program, while the user interfaces
+with it via a client, either running locally or connecting remotely.
+
+All of the code in the LLDB project is available under the Apache 2.0 License
+with LLVM exceptions.
+
+COMMANDS
+--------
+
+The first argument to lldb-server specifies a command to run.
+
+.. option:: v[ersion]
+
+ Prints lldb-server version and exits.
+
+.. option:: g[dbserver]
+
+ Runs the server using the gdb-remote protocol. LLDB can afterwards
+ connect to the server using *gdb-remote* command.
+
+.. option:: p[latform]
+
+ Runs the platform server. LLDB can afterwards connect to the server using
+ *platform select*, followed by *platform connect*.
+
+GDBSERVER COMMAND
+-----------------
+
+| :program:`lldb-server` g[dbserver] [*options*] [[*host*]:*port*] [[--] *program* *args*...]
+
+CONNECTION
+~~~~~~~~~~
+
+.. option:: host:port
+
+ Specifies the hostname and TCP port to listen on. Obligatory unless another
+ listening option is used. If host is empty, *localhost* will be used. If port
+ is zero, a random port will be selected, and written as specified by --pipe
+ or --named-pipe options.
+
+.. option:: --fd <fd>
+
+ Communicate over the given file descriptor instead of sockets.
+
+.. option:: --named-pipe <name>
+
+ Write the listening port number to the specified named pipe.
+
+.. option:: --pipe <fd>
+
+ Write the listening port number to the specified pipe (fd).
+
+.. option:: --reverse-connect
+
+ Connect to the client instead of passively waiting for a connection. In this
+ case, [host]:port denotes the remote address to connect to.
+
+GENERAL OPTIONS
+~~~~~~~~~~~~~~~
+
+.. option:: --help
+
+ Prints out the usage information and exits.
+
+.. option:: --log-channels <channel1 categories...:channel2 categories...>
+
+ Channels to log. A colon-separated list of entries. Each entry starts with
+ a channel followed by a space-separated list of categories.
+
+.. option:: --log-file <file>
+
+ Destination file to log to. If empty, log to stderr.
+
+.. option:: --setsid
+
+ Run lldb-server in a new session.
+
+TARGET SELECTION
+~~~~~~~~~~~~~~~~
+
+.. option:: --attach <pid-or-name>
+
+ Attach to the process given by a (numeric) process id or a name.
+
+.. option:: -- program args
+
+ Launch a program for debugging.
+
+If neither of target options are used, :program:`lldb-server` is started
+without a specific target. It can be afterwards instructed by the client
+to launch or attach.
+
+PLATFORM COMMAND
+----------------
+
+| :program:`lldb-server` p[latform] [*options*] --server --listen [[*host*]:*port*]
+
+CONNECTION
+~~~~~~~~~~
+
+.. option:: --server
+
+ Run in server mode, handling multiple connections. If this is not specified,
+ lldb-server will accept only one connection and exit when it is finished.
+
+.. option:: --listen <host>:<port>
+
+ Hostname and port to listen on. Obligatory. If *port* is zero, a random port
+ will be used.
+
+.. option:: --socket-file <path>
+
+ Write the listening socket port number to the specified file.
+
+GENERAL OPTIONS
+~~~~~~~~~~~~~~~
+
+.. option:: --log-channels <channel1 categories...:channel2 categories...>
+
+ Channels to log. A colon-separated list of entries. Each entry starts with
+ a channel followed by a space-separated list of categories.
+
+.. option:: --log-file <file>
+
+ Destination file to log to. If empty, log to stderr.
+
+GDB-SERVER CONNECTIONS
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. option:: --gdbserver-port <port>
+
+ Define a port to be used for gdb-server connections. Can be specified multiple
+ times to allow multiple ports. Has no effect if --min-gdbserver-port
+ and --max-gdbserver-port are specified.
+
+.. option:: --min-gdbserver-port <port>
+.. option:: --max-gdbserver-port <port>
+
+ Specify the range of ports that can be used for gdb-server connections. Both
+ options need to be specified simultaneously. Overrides --gdbserver-port.
+
+.. option:: --port-offset <offset>
+
+ Add the specified offset to port numbers returned by server. This is useful
+ if the server is running behind a firewall, and a range of ports is redirected
+ to it with an offset.
+
+EXAMPLES
+--------
+
+The server can be started in several modes.
+
+In order to launch a new process inside the debugger, pass the path to it
+and the arguments to the debugged executable as positional arguments.
+To disambiguate between arguments passed to lldb and arguments passed
+to the debugged executable, arguments starting with a - must be passed after
+--. The server will launch the new executable and stop it immediately, waiting
+for the client to connect.
+
+ lldb-server g :1234 /path/to/program program-argument -- --program-option
+
+For convenience, passing the executable after -- is also supported.
+
+ lldb-server g :1234 -- /path/to/program program-argument --program-option
+
+In order to attach to a running process, pass --attach along with the process
+identifier or name. The process will be stopped immediately after starting
+the server. Note that terminating the server will usually cause the process
+to be detached and continue execution.
+
+ lldb-server g :1234 --attach 12345
+ lldb-server g :1234 --attach program-name
+
+Use *gdb-remote* command to connect to the server:
+
+ (lldb) gdb-remote 1234
+
+lldb-server can also be started without an inferior. In this case, the client
+can select the target after connecting to the server. Note that some commands
+(e.g. *target create*) will disconnect and launch a local lldb-server instead.
+
+ lldb-server g :1234
+
+ (lldb) gdb-remote 1234
+ (lldb) process launch a.out
+
+SEE ALSO
+--------
+
+The LLDB project page https://lldb.llvm.org has many different resources
+for :program:`lldb-server` users.
diff --git a/contrib/llvm-project/lldb/docs/man/lldb.rst b/contrib/llvm-project/lldb/docs/man/lldb.rst
index 87be124d788e..b75288db380d 100644
--- a/contrib/llvm-project/lldb/docs/man/lldb.rst
+++ b/contrib/llvm-project/lldb/docs/man/lldb.rst
@@ -256,11 +256,11 @@ executable. To disambiguate between arguments passed to lldb and arguments
passed to the debugged executable, arguments starting with a - must be passed
after --.
- lldb --arch x86_64 /path/to/program program argument -- --arch arvm7
+ lldb --arch x86_64 /path/to/program program argument -- --arch armv7
For convenience, passing the executable after -- is also supported.
- lldb --arch x86_64 -- /path/to/program program argument --arch arvm7
+ lldb --arch x86_64 -- /path/to/program program argument --arch armv7
Passing one of the attach options causes :program:`lldb` to immediately attach
to the given process.
@@ -305,11 +305,17 @@ CONFIGURATION FILES
:program:`lldb` reads things like settings, aliases and commands from the
.lldbinit file.
-First, it will read the application specific init file whose name is
-~/.lldbinit followed by a "-" and the name of the current program. This would
-be ~/.lldbinit-lldb for the command line :program:`lldb` and ~/.lldbinit-Xcode
-for Xcode. If there is no application specific init file, the global
-~/.lldbinit is read.
+First, :program:`lldb` will try to read the application specific init file
+whose name is ~/.lldbinit followed by a "-" and the name of the current
+program. This would be ~/.lldbinit-lldb for the command line :program:`lldb`
+and ~/.lldbinit-Xcode for Xcode. If there is no application specific init
+file, :program:`lldb` will look for an init file in the home directory.
+If launched with a `REPL`_ option, it will first look for a REPL configuration
+file, specific to the REPL language. The init file should be named as follow:
+``.lldbinit-<language>-repl`` (i.e. ``.lldbinit-swift-repl``). If this file doesn't
+exist, or :program:`lldb` wasn't launch with `REPL`_, meaning there is neither
+a REPL init file nor an application specific init file, ``lldb`` will fallback to
+the global ~/.lldbinit.
Secondly, it will look for an .lldbinit file in the current working directory.
For security reasons, :program:`lldb` will print a warning and not source this
diff --git a/contrib/llvm-project/lldb/docs/python_api.rst b/contrib/llvm-project/lldb/docs/python_api.rst
new file mode 100644
index 000000000000..5e465e1eae68
--- /dev/null
+++ b/contrib/llvm-project/lldb/docs/python_api.rst
@@ -0,0 +1,98 @@
+LLDB Python API
+================================
+
+..
+ The long list of "skip" filters out several global functions that are
+ generated by SWIG (but which are not useful as they are only the
+ backend for their respective static functions in the classes).
+ Without this list
+.. automodapi:: lldb
+ :no-inheritance-diagram:
+ :skip: SBBreakpoint_EventIsBreakpointEvent
+ :skip: SBBreakpoint_GetBreakpointEventTypeFromEvent
+ :skip: SBBreakpoint_GetBreakpointFromEvent
+ :skip: SBBreakpoint_GetBreakpointLocationAtIndexFromEvent
+ :skip: SBBreakpoint_GetNumBreakpointLocationsFromEvent
+ :skip: SBCommandInterpreter_EventIsCommandInterpreterEvent
+ :skip: SBCommandInterpreter_GetArgumentDescriptionAsCString
+ :skip: SBCommandInterpreter_GetArgumentTypeAsCString
+ :skip: SBCommandInterpreter_GetBroadcasterClass
+ :skip: SBCommunication_GetBroadcasterClass
+ :skip: SBData_CreateDataFromCString
+ :skip: SBData_CreateDataFromDoubleArray
+ :skip: SBData_CreateDataFromSInt32Array
+ :skip: SBData_CreateDataFromSInt64Array
+ :skip: SBData_CreateDataFromUInt32Array
+ :skip: SBData_CreateDataFromUInt64Array
+ :skip: SBDebugger_Create
+ :skip: SBDebugger_Create
+ :skip: SBDebugger_Destroy
+ :skip: SBDebugger_FindDebuggerWithID
+ :skip: SBDebugger_GetBuildConfiguration
+ :skip: SBDebugger_GetDefaultArchitecture
+ :skip: SBDebugger_GetInternalVariableValue
+ :skip: SBDebugger_GetVersionString
+ :skip: SBDebugger_Initialize
+ :skip: SBDebugger_InitializeWithErrorHandling
+ :skip: SBDebugger_MemoryPressureDetected
+ :skip: SBDebugger_SetDefaultArchitecture
+ :skip: SBDebugger_SetInternalVariable
+ :skip: SBDebugger_StateAsCString
+ :skip: SBDebugger_StateIsRunningState
+ :skip: SBDebugger_StateIsStoppedState
+ :skip: SBDebugger_Terminate
+ :skip: SBEvent_GetCStringFromEvent
+ :skip: SBFileSpec_ResolvePath
+ :skip: SBFile_MakeBorrowed
+ :skip: SBFile_MakeBorrowedForcingIOMethods
+ :skip: SBFile_MakeForcingIOMethods
+ :skip: SBHostOS_GetLLDBPath
+ :skip: SBHostOS_GetLLDBPythonPath
+ :skip: SBHostOS_GetProgramFileSpec
+ :skip: SBHostOS_GetUserHomeDirectory
+ :skip: SBHostOS_ThreadCancel
+ :skip: SBHostOS_ThreadCreate
+ :skip: SBHostOS_ThreadCreated
+ :skip: SBHostOS_ThreadDetach
+ :skip: SBHostOS_ThreadJoin
+ :skip: SBLanguageRuntime_GetLanguageTypeFromString
+ :skip: SBLanguageRuntime_GetNameForLanguageType
+ :skip: SBModuleSpecList_GetModuleSpecifications
+ :skip: SBModule_GarbageCollectAllocatedModules
+ :skip: SBModule_GetNumberAllocatedModules
+ :skip: SBPlatform_GetHostPlatform
+ :skip: SBProcess_EventIsProcessEvent
+ :skip: SBProcess_EventIsStructuredDataEvent
+ :skip: SBProcess_GetBroadcasterClassName
+ :skip: SBProcess_GetInterruptedFromEvent
+ :skip: SBProcess_GetNumRestartedReasonsFromEvent
+ :skip: SBProcess_GetProcessFromEvent
+ :skip: SBProcess_GetRestartedFromEvent
+ :skip: SBProcess_GetRestartedReasonAtIndexFromEvent
+ :skip: SBProcess_GetStateFromEvent
+ :skip: SBProcess_GetStructuredDataFromEvent
+ :skip: SBReproducer_Capture
+ :skip: SBReproducer_PassiveReplay
+ :skip: SBReproducer_SetAutoGenerate
+ :skip: SBReproducer_SetWorkingDirectory
+ :skip: SBTarget_EventIsTargetEvent
+ :skip: SBTarget_GetBroadcasterClassName
+ :skip: SBTarget_GetModuleAtIndexFromEvent
+ :skip: SBTarget_GetNumModulesFromEvent
+ :skip: SBTarget_GetTargetFromEvent
+ :skip: SBThread_EventIsThreadEvent
+ :skip: SBThread_GetBroadcasterClassName
+ :skip: SBThread_GetStackFrameFromEvent
+ :skip: SBThread_GetThreadFromEvent
+ :skip: SBTypeSummary_CreateWithFunctionName
+ :skip: SBTypeSummary_CreateWithScriptCode
+ :skip: SBTypeSummary_CreateWithSummaryString
+ :skip: SBTypeSynthetic_CreateWithClassName
+ :skip: SBTypeSynthetic_CreateWithScriptCode
+ :skip: SBWatchpoint_EventIsWatchpointEvent
+ :skip: SBWatchpoint_GetWatchpointEventTypeFromEvent
+ :skip: SBWatchpoint_GetWatchpointFromEvent
+ :skip: command
+ :skip: in_range
+ :skip: is_numeric_type
+ :skip: lldb_iter
diff --git a/contrib/llvm-project/lldb/docs/python_api_enums.rst b/contrib/llvm-project/lldb/docs/python_api_enums.rst
new file mode 100644
index 000000000000..b00ac47bd1fa
--- /dev/null
+++ b/contrib/llvm-project/lldb/docs/python_api_enums.rst
@@ -0,0 +1,1257 @@
+..
+ This is a sub page of the Python API docs and linked from the main API page.
+ The page isn't in any toctree, so silence the sphinx warnings by marking it as orphan.
+
+:orphan:
+
+Python API enumerators and constants
+====================================
+
+.. py:currentmodule:: lldb
+
+Constants
+*********
+
+Generic register numbers
+------------------------
+
+.. py:data:: LLDB_REGNUM_GENERIC_PC
+
+ Program counter.
+
+.. py:data:: LLDB_REGNUM_GENERIC_SP
+
+ Stack pointer.
+.. py:data:: LLDB_REGNUM_GENERIC_FP
+
+ Frame pointer.
+
+.. py:data:: LLDB_REGNUM_GENERIC_RA
+
+ Return address.
+
+.. py:data:: LLDB_REGNUM_GENERIC_FLAGS
+
+ Processor flags register.
+
+.. py:data:: LLDB_REGNUM_GENERIC_ARG1
+
+ The register that would contain pointer size or less argument 1 (if any).
+
+.. py:data:: LLDB_REGNUM_GENERIC_ARG2
+
+ The register that would contain pointer size or less argument 2 (if any).
+
+.. py:data:: LLDB_REGNUM_GENERIC_ARG3
+
+ The register that would contain pointer size or less argument 3 (if any).
+
+.. py:data:: LLDB_REGNUM_GENERIC_ARG4
+
+ The register that would contain pointer size or less argument 4 (if any).
+
+.. py:data:: LLDB_REGNUM_GENERIC_ARG5
+
+ The register that would contain pointer size or less argument 5 (if any).
+
+.. py:data:: LLDB_REGNUM_GENERIC_ARG6
+
+ The register that would contain pointer size or less argument 6 (if any).
+
+.. py:data:: LLDB_REGNUM_GENERIC_ARG7
+
+ The register that would contain pointer size or less argument 7 (if any).
+
+.. py:data:: LLDB_REGNUM_GENERIC_ARG8
+
+ The register that would contain pointer size or less argument 8 (if any).
+
+
+Invalid value definitions
+-------------------------
+
+.. py:data:: LLDB_INVALID_BREAK_ID
+.. py:data:: LLDB_INVALID_WATCH_ID
+.. py:data:: LLDB_INVALID_ADDRESS
+.. py:data:: LLDB_INVALID_INDEX32
+.. py:data:: LLDB_INVALID_IVAR_OFFSET
+.. py:data:: LLDB_INVALID_IMAGE_TOKEN
+.. py:data:: LLDB_INVALID_MODULE_VERSION
+.. py:data:: LLDB_INVALID_REGNUM
+.. py:data:: LLDB_INVALID_UID
+.. py:data:: LLDB_INVALID_PROCESS_ID
+.. py:data:: LLDB_INVALID_THREAD_ID
+.. py:data:: LLDB_INVALID_FRAME_ID
+.. py:data:: LLDB_INVALID_SIGNAL_NUMBER
+.. py:data:: LLDB_INVALID_OFFSET
+.. py:data:: LLDB_INVALID_LINE_NUMBER
+.. py:data:: LLDB_INVALID_QUEUE_ID
+
+CPU types
+---------
+
+.. py:data:: LLDB_ARCH_DEFAULT
+.. py:data:: LLDB_ARCH_DEFAULT_32BIT
+.. py:data:: LLDB_ARCH_DEFAULT_64BIT
+.. py:data:: LLDB_INVALID_CPUTYPE
+
+
+Option set definitions
+----------------------
+
+.. py:data:: LLDB_MAX_NUM_OPTION_SETS
+.. py:data:: LLDB_OPT_SET_ALL
+.. py:data:: LLDB_OPT_SET_1
+.. py:data:: LLDB_OPT_SET_2
+.. py:data:: LLDB_OPT_SET_3
+.. py:data:: LLDB_OPT_SET_4
+.. py:data:: LLDB_OPT_SET_5
+.. py:data:: LLDB_OPT_SET_6
+.. py:data:: LLDB_OPT_SET_7
+.. py:data:: LLDB_OPT_SET_8
+.. py:data:: LLDB_OPT_SET_9
+.. py:data:: LLDB_OPT_SET_10
+.. py:data:: LLDB_OPT_SET_11
+
+Miscellaneous constants
+------------------------
+
+.. py:data:: LLDB_GENERIC_ERROR
+.. py:data:: LLDB_DEFAULT_BREAK_SIZE
+.. py:data:: LLDB_WATCH_TYPE_READ
+.. py:data:: LLDB_WATCH_TYPE_WRITE
+
+
+Enumerators
+***********
+
+State
+-----
+
+.. py:data:: eStateInvalid
+.. py:data:: eStateUnloaded
+
+ Process is object is valid, but not currently loaded.
+
+.. py:data:: eStateConnected
+
+ Process is connected to remote debug services, but not
+ launched or attached to anything yet.
+
+.. py:data:: eStateAttaching
+
+ Process is in the process of launching.
+
+.. py:data:: eStateLaunching
+
+ Process is in the process of launching.
+
+.. py:data:: eStateStopped
+
+ Process or thread is stopped and can be examined.
+
+.. py:data:: eStateRunning
+
+ Process or thread is running and can't be examined.
+
+.. py:data:: eStateStepping
+
+ Process or thread is in the process of stepping and can
+ not be examined.
+
+.. py:data:: eStateCrashed
+
+ Process or thread has crashed and can be examined.
+
+.. py:data:: eStateDetached
+
+ Process has been detached and can't be examined.
+
+.. py:data:: eStateExited
+
+ Process has exited and can't be examined.
+
+.. py:data:: eStateSuspended
+
+ Process or thread is in a suspended state as far
+ as the debugger is concerned while other processes
+ or threads get the chance to run.
+
+LaunchFlag
+----------
+
+.. py:data:: eLaunchFlagNone
+.. py:data:: eLaunchFlagExec
+
+ Exec when launching and turn the calling process into a new process.
+
+.. py:data:: eLaunchFlagDebug
+
+ Stop as soon as the process launches to allow the process to be debugged.
+
+.. py:data:: eLaunchFlagStopAtEntry
+
+ Stop at the program entry point instead of auto-continuing when launching or attaching at entry point.
+
+.. py:data:: eLaunchFlagDisableASLR
+
+ Disable Address Space Layout Randomization.
+
+.. py:data:: eLaunchFlagDisableSTDIO
+
+ Disable stdio for inferior process (e.g. for a GUI app).
+
+.. py:data:: eLaunchFlagLaunchInTTY
+
+ Launch the process in a new TTY if supported by the host.
+
+.. py:data:: eLaunchFlagLaunchInShell
+
+ Launch the process inside a shell to get shell expansion.
+
+.. py:data:: eLaunchFlagLaunchInSeparateProcessGroup
+
+ Launch the process in a separate process group if you are going to hand the process off (e.g. to debugserver)
+
+.. py:data:: eLaunchFlagDontSetExitStatus
+
+ set this flag so lldb & the handee don't race to set its exit status.
+
+.. py:data:: eLaunchFlagDetachOnError
+
+ If set, then the client stub should detach rather than killing the debugee
+ if it loses connection with lldb.
+
+.. py:data:: eLaunchFlagShellExpandArguments
+
+ Perform shell-style argument expansion
+
+.. py:data:: eLaunchFlagCloseTTYOnExit
+
+ Close the open TTY on exit
+
+.. py:data:: eLaunchFlagInheritTCCFromParent
+
+ Don't make the inferior responsible for its own TCC
+ permissions but instead inherit them from its parent.
+
+RunMode
+-------
+.. py:data:: eOnlyThisThread
+.. py:data:: eAllThreads
+.. py:data:: eOnlyDuringStepping
+
+
+ByteOrder
+---------
+
+.. py:data:: eByteOrderInvalid
+.. py:data:: eByteOrderBig
+.. py:data:: eByteOrderPDP
+.. py:data:: eByteOrderLittle
+
+Encoding
+--------
+
+.. py:data:: eEncodingInvalid
+.. py:data:: eEncodingUint
+.. py:data:: eEncodingSint
+.. py:data:: eEncodingIEEE754
+.. py:data:: eEncodingVector
+
+Format
+------
+
+.. py:data:: eFormatDefault
+.. py:data:: eFormatInvalid
+.. py:data:: eFormatBoolean
+.. py:data:: eFormatBinary
+.. py:data:: eFormatBytes
+.. py:data:: eFormatBytesWithASCII
+.. py:data:: eFormatChar
+.. py:data:: eFormatCharPrintable
+.. py:data:: eFormatComplex
+.. py:data:: eFormatComplexFloat
+.. py:data:: eFormatCString
+.. py:data:: eFormatDecimal
+.. py:data:: eFormatEnum
+.. py:data:: eFormatHex
+.. py:data:: eFormatHexUppercase
+.. py:data:: eFormatFloat
+.. py:data:: eFormatOctal
+.. py:data:: eFormatOSType
+.. py:data:: eFormatUnicode16
+.. py:data:: eFormatUnicode32
+.. py:data:: eFormatUnsigned
+.. py:data:: eFormatPointer
+.. py:data:: eFormatVectorOfChar
+.. py:data:: eFormatVectorOfSInt8
+.. py:data:: eFormatVectorOfUInt8
+.. py:data:: eFormatVectorOfSInt16
+.. py:data:: eFormatVectorOfUInt16
+.. py:data:: eFormatVectorOfSInt32
+.. py:data:: eFormatVectorOfUInt32
+.. py:data:: eFormatVectorOfSInt64
+.. py:data:: eFormatVectorOfUInt64
+.. py:data:: eFormatVectorOfFloat16
+.. py:data:: eFormatVectorOfFloat32
+.. py:data:: eFormatVectorOfFloat64
+.. py:data:: eFormatVectorOfUInt128
+.. py:data:: eFormatComplexInteger
+.. py:data:: eFormatCharArray
+.. py:data:: eFormatAddressInfo
+.. py:data:: eFormatHexFloat
+.. py:data:: eFormatInstruction
+.. py:data:: eFormatVoid
+.. py:data:: eFormatUnicode8
+
+DescriptionLevel
+----------------
+
+.. py:data:: eDescriptionLevelBrief
+.. py:data:: eDescriptionLevelFull
+.. py:data:: eDescriptionLevelVerbose
+.. py:data:: eDescriptionLevelInitial
+
+ScriptLanguage
+--------------
+
+.. py:data:: eScriptLanguageNone
+.. py:data:: eScriptLanguagePython
+.. py:data:: eScriptLanguageLua
+.. py:data:: eScriptLanguageUnknown
+.. py:data:: eScriptLanguageDefault
+
+RegisterKind
+------------
+
+.. py:data:: eRegisterKindEHFrame
+.. py:data:: eRegisterKindDWARF
+.. py:data:: eRegisterKindGeneric
+.. py:data:: eRegisterKindProcessPlugin
+.. py:data:: eRegisterKindLLDB
+
+StopReason
+----------
+
+.. py:data:: eStopReasonInvalid
+.. py:data:: eStopReasonNone
+.. py:data:: eStopReasonTrace
+.. py:data:: eStopReasonBreakpoint
+.. py:data:: eStopReasonWatchpoint
+.. py:data:: eStopReasonSignal
+.. py:data:: eStopReasonException
+.. py:data:: eStopReasonExec
+.. py:data:: eStopReasonPlanComplete
+.. py:data:: eStopReasonThreadExiting
+.. py:data:: eStopReasonInstrumentation
+
+ReturnStatus
+------------
+
+.. py:data:: eReturnStatusInvalid
+.. py:data:: eReturnStatusSuccessFinishNoResult
+.. py:data:: eReturnStatusSuccessFinishResult
+.. py:data:: eReturnStatusSuccessContinuingNoResult
+.. py:data:: eReturnStatusSuccessContinuingResult
+.. py:data:: eReturnStatusStarted
+.. py:data:: eReturnStatusFailed
+.. py:data:: eReturnStatusQuit
+
+Expression
+----------
+
+The results of expression evaluation.
+
+.. py:data:: eExpressionCompleted
+.. py:data:: eExpressionSetupError
+.. py:data:: eExpressionParseError
+.. py:data:: eExpressionDiscarded
+.. py:data:: eExpressionInterrupted
+.. py:data:: eExpressionHitBreakpoint
+.. py:data:: eExpressionTimedOut
+.. py:data:: eExpressionResultUnavailable
+.. py:data:: eExpressionStoppedForDebug
+.. py:data:: eExpressionThreadVanished
+
+SearchDepth
+-----------
+
+.. py:data:: eSearchDepthInvalid
+.. py:data:: eSearchDepthTarget
+.. py:data:: eSearchDepthModule
+.. py:data:: eSearchDepthCompUnit
+.. py:data:: eSearchDepthFunction
+.. py:data:: eSearchDepthBlock
+.. py:data:: eSearchDepthAddress
+
+ConnectionStatus
+----------------
+
+.. py:data:: eConnectionStatusSuccess
+
+ Success.
+
+.. py:data:: eConnectionStatusEndOfFile
+
+ End-of-file encountered.
+
+.. py:data:: eConnectionStatusError
+
+ Error encountered.
+
+.. py:data:: eConnectionStatusTimedOut
+
+ Request timed out.
+
+.. py:data:: eConnectionStatusNoConnection
+
+ No connection.
+
+.. py:data:: eConnectionStatusLostConnection
+
+ Lost connection while connected to a valid connection.
+
+.. py:data:: eConnectionStatusInterrupted
+
+ Interrupted read.
+
+ErrorType
+---------
+
+.. py:data:: eErrorTypeInvalid
+.. py:data:: eErrorTypeGeneric
+
+ Generic errors that can be any value.
+
+.. py:data:: eErrorTypeMachKernel
+
+ Mach kernel error codes.
+
+.. py:data:: eErrorTypePOSIX
+
+ POSIX error codes.
+
+.. py:data:: eErrorTypeExpression
+
+ These are from the ExpressionResults enum.
+
+.. py:data:: eErrorTypeWin32
+
+ Standard Win32 error codes.
+
+
+ValueType
+---------
+
+.. py:data:: eValueTypeInvalid
+.. py:data:: eValueTypeVariableGlobal
+
+ Global variable.
+
+.. py:data:: eValueTypeVariableStatic
+
+ Static variable.
+
+.. py:data:: eValueTypeVariableArgument
+
+ Funfction argument variable.
+
+.. py:data:: eValueTypeVariableLocal
+
+ Function local variable.
+
+.. py:data:: eValueTypeRegister
+
+ Stack frame register.
+
+.. py:data:: eValueTypeRegisterSet
+
+ A collection of stack frame register values.
+
+.. py:data:: eValueTypeConstResult
+
+ Constant result variables.
+
+.. py:data:: eValueTypeVariableThreadLocal
+
+ Thread local storage variable.
+
+InputReader
+-----------
+
+Token size/granularities for Input Readers.
+
+.. py:data:: eInputReaderGranularityInvalid
+.. py:data:: eInputReaderGranularityByte
+.. py:data:: eInputReaderGranularityWord
+.. py:data:: eInputReaderGranularityLine
+.. py:data:: eInputReaderGranularityAll
+
+SymbolContextItem
+-----------------
+
+These mask bits allow a common interface for queries that can
+limit the amount of information that gets parsed to only the
+information that is requested. These bits also can indicate what
+actually did get resolved during query function calls.
+
+Each definition corresponds to a one of the member variables
+in this class, and requests that that item be resolved, or
+indicates that the member did get resolved.
+
+.. py:data:: eSymbolContextTarget
+
+ Set when target is requested from a query, or was located
+ in query results.
+
+.. py:data:: eSymbolContextModule
+
+ Set when module is requested from a query, or was located
+ in query results.
+
+.. py:data:: eSymbolContextCompUnit
+
+ Set when compilation unit is requested from a query, or was
+ located in query results.
+
+.. py:data:: eSymbolContextFunction
+
+ Set when function is requested from a query, or was located
+ in query results.
+
+.. py:data:: eSymbolContextBlock
+
+ Set when the deepest block is requested from a query, or
+ was located in query results.
+
+.. py:data:: eSymbolContextLineEntry
+
+ Set when line entry is requested from a query, or was
+ located in query results.
+
+.. py:data:: eSymbolContextSymbol
+
+ Set when symbol is requested from a query, or was located
+ in query results
+
+.. py:data:: eSymbolContextEverything
+
+ Indicates to try and lookup everything up during a routine
+ symbol context query.
+
+.. py:data:: eSymbolContextVariable
+
+ Set when global or static variable is requested from a
+ query, or was located in query results.
+ eSymbolContextVariable is potentially expensive to lookup so
+ it isn't included in eSymbolContextEverything which stops it
+ from being used during frame PC lookups and many other
+ potential address to symbol context lookups.
+
+Permissions
+-----------
+.. py:data:: ePermissionsWritable
+.. py:data:: ePermissionsReadable
+.. py:data:: ePermissionsExecutable
+
+InputReader
+-----------
+
+.. py:data:: eInputReaderActivate
+
+ Reader is newly pushed onto the reader stack.
+
+.. py:data:: eInputReaderAsynchronousOutputWritten
+
+ An async output event occurred; the reader may want to do something.
+
+.. py:data:: eInputReaderReactivate
+
+ Reader is on top of the stack again after another reader was popped off.
+
+.. py:data:: eInputReaderDeactivate
+
+ Another reader was pushed on the stack.
+
+.. py:data:: eInputReaderGotToken
+
+ Reader got one of its tokens (granularity).
+
+.. py:data:: eInputReaderInterrupt
+
+ Reader received an interrupt signal (probably from a control-c).
+
+.. py:data:: eInputReaderEndOfFile
+
+ Reader received an EOF char (probably from a control-d).
+
+.. py:data:: eInputReaderDone
+
+ Reader was just popped off the stack and is done.
+
+BreakpointEventType
+-------------------
+
+.. py:data:: eBreakpointEventTypeInvalidType
+.. py:data:: eBreakpointEventTypeAdded
+.. py:data:: eBreakpointEventTypeRemoved
+.. py:data:: eBreakpointEventTypeLocationsAdded
+.. py:data:: eBreakpointEventTypeLocationsRemoved
+.. py:data:: eBreakpointEventTypeLocationsResolved
+.. py:data:: eBreakpointEventTypeEnabled
+.. py:data:: eBreakpointEventTypeDisabled
+.. py:data:: eBreakpointEventTypeCommandChanged
+.. py:data:: eBreakpointEventTypeConditionChanged
+.. py:data:: eBreakpointEventTypeIgnoreChanged
+.. py:data:: eBreakpointEventTypeThreadChanged
+.. py:data:: eBreakpointEventTypeAutoContinueChanged
+
+WatchpointEventType
+-------------------
+
+.. py:data:: eWatchpointEventTypeInvalidType
+.. py:data:: eWatchpointEventTypeAdded
+.. py:data:: eWatchpointEventTypeRemoved
+.. py:data:: eWatchpointEventTypeEnabled
+.. py:data:: eWatchpointEventTypeDisabled
+.. py:data:: eWatchpointEventTypeCommandChanged
+.. py:data:: eWatchpointEventTypeConditionChanged
+.. py:data:: eWatchpointEventTypeIgnoreChanged
+.. py:data:: eWatchpointEventTypeThreadChanged
+.. py:data:: eWatchpointEventTypeTypeChanged
+
+.. _LanguageType:
+
+LanguageType
+------------
+
+.. py:data:: eLanguageTypeUnknown
+.. py:data:: eLanguageTypeC89
+.. py:data:: eLanguageTypeC
+.. py:data:: eLanguageTypeAda83
+.. py:data:: eLanguageTypeC_plus_plus
+.. py:data:: eLanguageTypeCobol74
+.. py:data:: eLanguageTypeCobol85
+.. py:data:: eLanguageTypeFortran77
+.. py:data:: eLanguageTypeFortran90
+.. py:data:: eLanguageTypePascal83
+.. py:data:: eLanguageTypeModula2
+.. py:data:: eLanguageTypeJava
+.. py:data:: eLanguageTypeC99
+.. py:data:: eLanguageTypeAda95
+.. py:data:: eLanguageTypeFortran95
+.. py:data:: eLanguageTypePLI
+.. py:data:: eLanguageTypeObjC
+.. py:data:: eLanguageTypeObjC_plus_plus
+.. py:data:: eLanguageTypeUPC
+.. py:data:: eLanguageTypeD
+.. py:data:: eLanguageTypePython
+.. py:data:: eLanguageTypeOpenCL
+.. py:data:: eLanguageTypeGo
+.. py:data:: eLanguageTypeModula3
+.. py:data:: eLanguageTypeHaskell
+.. py:data:: eLanguageTypeC_plus_plus_03
+.. py:data:: eLanguageTypeC_plus_plus_11
+.. py:data:: eLanguageTypeOCaml
+.. py:data:: eLanguageTypeRust
+.. py:data:: eLanguageTypeC11
+.. py:data:: eLanguageTypeSwift
+.. py:data:: eLanguageTypeJulia
+.. py:data:: eLanguageTypeDylan
+.. py:data:: eLanguageTypeC_plus_plus_14
+.. py:data:: eLanguageTypeFortran03
+.. py:data:: eLanguageTypeFortran08
+.. py:data:: eLanguageTypeMipsAssembler
+.. py:data:: eLanguageTypeExtRenderScript
+.. py:data:: eNumLanguageTypes
+
+InstrumentationRuntimeType
+--------------------------
+
+.. py:data:: eInstrumentationRuntimeTypeAddressSanitizer
+.. py:data:: eInstrumentationRuntimeTypeThreadSanitizer
+.. py:data:: eInstrumentationRuntimeTypeUndefinedBehaviorSanitizer
+.. py:data:: eInstrumentationRuntimeTypeMainThreadChecker
+.. py:data:: eInstrumentationRuntimeTypeSwiftRuntimeReporting
+.. py:data:: eNumInstrumentationRuntimeTypes
+
+DynamicValueType
+----------------
+
+.. py:data:: eNoDynamicValues
+.. py:data:: eDynamicCanRunTarget
+.. py:data:: eDynamicDontRunTarget
+
+StopShowColumn
+--------------
+
+.. py:data:: eStopShowColumnAnsiOrCaret
+.. py:data:: eStopShowColumnAnsi
+.. py:data:: eStopShowColumnCaret
+.. py:data:: eStopShowColumnNone
+
+AccessType
+----------
+
+.. py:data:: eAccessNone
+.. py:data:: eAccessPublic
+.. py:data:: eAccessPrivate
+.. py:data:: eAccessProtected
+.. py:data:: eAccessPackage
+
+CommandArgumentType
+-------------------
+
+.. py:data:: eArgTypeAddress
+.. py:data:: eArgTypeAddressOrExpression
+.. py:data:: eArgTypeAliasName
+.. py:data:: eArgTypeAliasOptions
+.. py:data:: eArgTypeArchitecture
+.. py:data:: eArgTypeBoolean
+.. py:data:: eArgTypeBreakpointID
+.. py:data:: eArgTypeBreakpointIDRange
+.. py:data:: eArgTypeBreakpointName
+.. py:data:: eArgTypeByteSize
+.. py:data:: eArgTypeClassName
+.. py:data:: eArgTypeCommandName
+.. py:data:: eArgTypeCount
+.. py:data:: eArgTypeDescriptionVerbosity
+.. py:data:: eArgTypeDirectoryName
+.. py:data:: eArgTypeDisassemblyFlavor
+.. py:data:: eArgTypeEndAddress
+.. py:data:: eArgTypeExpression
+.. py:data:: eArgTypeExpressionPath
+.. py:data:: eArgTypeExprFormat
+.. py:data:: eArgTypeFileLineColumn
+.. py:data:: eArgTypeFilename
+.. py:data:: eArgTypeFormat
+.. py:data:: eArgTypeFrameIndex
+.. py:data:: eArgTypeFullName
+.. py:data:: eArgTypeFunctionName
+.. py:data:: eArgTypeFunctionOrSymbol
+.. py:data:: eArgTypeGDBFormat
+.. py:data:: eArgTypeHelpText
+.. py:data:: eArgTypeIndex
+.. py:data:: eArgTypeLanguage
+.. py:data:: eArgTypeLineNum
+.. py:data:: eArgTypeLogCategory
+.. py:data:: eArgTypeLogChannel
+.. py:data:: eArgTypeMethod
+.. py:data:: eArgTypeName
+.. py:data:: eArgTypeNewPathPrefix
+.. py:data:: eArgTypeNumLines
+.. py:data:: eArgTypeNumberPerLine
+.. py:data:: eArgTypeOffset
+.. py:data:: eArgTypeOldPathPrefix
+.. py:data:: eArgTypeOneLiner
+.. py:data:: eArgTypePath
+.. py:data:: eArgTypePermissionsNumber
+.. py:data:: eArgTypePermissionsString
+.. py:data:: eArgTypePid
+.. py:data:: eArgTypePlugin
+.. py:data:: eArgTypeProcessName
+.. py:data:: eArgTypePythonClass
+.. py:data:: eArgTypePythonFunction
+.. py:data:: eArgTypePythonScript
+.. py:data:: eArgTypeQueueName
+.. py:data:: eArgTypeRegisterName
+.. py:data:: eArgTypeRegularExpression
+.. py:data:: eArgTypeRunArgs
+.. py:data:: eArgTypeRunMode
+.. py:data:: eArgTypeScriptedCommandSynchronicity
+.. py:data:: eArgTypeScriptLang
+.. py:data:: eArgTypeSearchWord
+.. py:data:: eArgTypeSelector
+.. py:data:: eArgTypeSettingIndex
+.. py:data:: eArgTypeSettingKey
+.. py:data:: eArgTypeSettingPrefix
+.. py:data:: eArgTypeSettingVariableName
+.. py:data:: eArgTypeShlibName
+.. py:data:: eArgTypeSourceFile
+.. py:data:: eArgTypeSortOrder
+.. py:data:: eArgTypeStartAddress
+.. py:data:: eArgTypeSummaryString
+.. py:data:: eArgTypeSymbol
+.. py:data:: eArgTypeThreadID
+.. py:data:: eArgTypeThreadIndex
+.. py:data:: eArgTypeThreadName
+.. py:data:: eArgTypeTypeName
+.. py:data:: eArgTypeUnsignedInteger
+.. py:data:: eArgTypeUnixSignal
+.. py:data:: eArgTypeVarName
+.. py:data:: eArgTypeValue
+.. py:data:: eArgTypeWidth
+.. py:data:: eArgTypeNone
+.. py:data:: eArgTypePlatform
+.. py:data:: eArgTypeWatchpointID
+.. py:data:: eArgTypeWatchpointIDRange
+.. py:data:: eArgTypeWatchType
+.. py:data:: eArgRawInput
+.. py:data:: eArgTypeCommand
+.. py:data:: eArgTypeColumnNum
+.. py:data:: eArgTypeModuleUUID
+.. py:data:: eArgTypeLastArg
+
+SymbolType
+----------
+
+.. py:data:: eSymbolTypeAny
+.. py:data:: eSymbolTypeInvalid
+.. py:data:: eSymbolTypeAbsolute
+.. py:data:: eSymbolTypeCode
+.. py:data:: eSymbolTypeResolver
+.. py:data:: eSymbolTypeData
+.. py:data:: eSymbolTypeTrampoline
+.. py:data:: eSymbolTypeRuntime
+.. py:data:: eSymbolTypeException
+.. py:data:: eSymbolTypeSourceFile
+.. py:data:: eSymbolTypeHeaderFile
+.. py:data:: eSymbolTypeObjectFile
+.. py:data:: eSymbolTypeCommonBlock
+.. py:data:: eSymbolTypeBlock
+.. py:data:: eSymbolTypeLocal
+.. py:data:: eSymbolTypeParam
+.. py:data:: eSymbolTypeVariable
+.. py:data:: eSymbolTypeVariableType
+.. py:data:: eSymbolTypeLineEntry
+.. py:data:: eSymbolTypeLineHeader
+.. py:data:: eSymbolTypeScopeBegin
+.. py:data:: eSymbolTypeScopeEnd
+.. py:data:: eSymbolTypeAdditional
+.. py:data:: eSymbolTypeCompiler
+.. py:data:: eSymbolTypeInstrumentation
+.. py:data:: eSymbolTypeUndefined
+.. py:data:: eSymbolTypeObjCClass
+.. py:data:: eSymbolTypeObjCMetaClass
+.. py:data:: eSymbolTypeObjCIVar
+.. py:data:: eSymbolTypeReExported
+
+SectionType
+-----------
+
+.. py:data:: eSectionTypeInvalid
+.. py:data:: eSectionTypeCode
+.. py:data:: eSectionTypeContainer
+.. py:data:: eSectionTypeData
+.. py:data:: eSectionTypeDataCString
+.. py:data:: eSectionTypeDataCStringPointers
+.. py:data:: eSectionTypeDataSymbolAddress
+.. py:data:: eSectionTypeData4
+.. py:data:: eSectionTypeData8
+.. py:data:: eSectionTypeData16
+.. py:data:: eSectionTypeDataPointers
+.. py:data:: eSectionTypeDebug
+.. py:data:: eSectionTypeZeroFill
+.. py:data:: eSectionTypeDataObjCMessageRefs
+.. py:data:: eSectionTypeDataObjCCFStrings
+.. py:data:: eSectionTypeDWARFDebugAbbrev
+.. py:data:: eSectionTypeDWARFDebugAddr
+.. py:data:: eSectionTypeDWARFDebugAranges
+.. py:data:: eSectionTypeDWARFDebugCuIndex
+.. py:data:: eSectionTypeDWARFDebugFrame
+.. py:data:: eSectionTypeDWARFDebugInfo
+.. py:data:: eSectionTypeDWARFDebugLine
+.. py:data:: eSectionTypeDWARFDebugLoc
+.. py:data:: eSectionTypeDWARFDebugMacInfo
+.. py:data:: eSectionTypeDWARFDebugMacro
+.. py:data:: eSectionTypeDWARFDebugPubNames
+.. py:data:: eSectionTypeDWARFDebugPubTypes
+.. py:data:: eSectionTypeDWARFDebugRanges
+.. py:data:: eSectionTypeDWARFDebugStr
+.. py:data:: eSectionTypeDWARFDebugStrOffsets
+.. py:data:: eSectionTypeDWARFAppleNames
+.. py:data:: eSectionTypeDWARFAppleTypes
+.. py:data:: eSectionTypeDWARFAppleNamespaces
+.. py:data:: eSectionTypeDWARFAppleObjC
+.. py:data:: eSectionTypeELFSymbolTable
+.. py:data:: eSectionTypeELFDynamicSymbols
+.. py:data:: eSectionTypeELFRelocationEntries
+.. py:data:: eSectionTypeELFDynamicLinkInfo
+.. py:data:: eSectionTypeEHFrame
+.. py:data:: eSectionTypeARMexidx
+.. py:data:: eSectionTypeARMextab
+.. py:data:: eSectionTypeCompactUnwind
+.. py:data:: eSectionTypeGoSymtab
+.. py:data:: eSectionTypeAbsoluteAddress
+.. py:data:: eSectionTypeDWARFGNUDebugAltLink
+.. py:data:: eSectionTypeDWARFDebugTypes
+.. py:data:: eSectionTypeDWARFDebugNames
+.. py:data:: eSectionTypeOther
+.. py:data:: eSectionTypeDWARFDebugLineStr
+.. py:data:: eSectionTypeDWARFDebugRngLists
+.. py:data:: eSectionTypeDWARFDebugLocLists
+.. py:data:: eSectionTypeDWARFDebugAbbrevDwo
+.. py:data:: eSectionTypeDWARFDebugInfoDwo
+.. py:data:: eSectionTypeDWARFDebugStrDwo
+.. py:data:: eSectionTypeDWARFDebugStrOffsetsDwo
+.. py:data:: eSectionTypeDWARFDebugTypesDwo
+.. py:data:: eSectionTypeDWARFDebugRngListsDwo
+.. py:data:: eSectionTypeDWARFDebugLocDwo
+.. py:data:: eSectionTypeDWARFDebugLocListsDwo
+.. py:data:: eSectionTypeDWARFDebugTuIndex
+
+EmulatorInstructionOption
+-------------------------
+
+.. py:data:: eEmulateInstructionOptionNone
+.. py:data:: eEmulateInstructionOptionAutoAdvancePC
+.. py:data:: eEmulateInstructionOptionIgnoreConditions
+
+FunctionNameType
+----------------
+
+.. py:data:: eFunctionNameTypeNone
+.. py:data:: eFunctionNameTypeAuto
+.. py:data:: eFunctionNameTypeFull
+.. py:data:: eFunctionNameTypeBase
+.. py:data:: eFunctionNameTypeMethod
+.. py:data:: eFunctionNameTypeSelector
+.. py:data:: eFunctionNameTypeAny
+
+BasicType
+---------
+
+.. py:data:: eBasicTypeInvalid
+.. py:data:: eBasicTypeVoid
+.. py:data:: eBasicTypeChar
+.. py:data:: eBasicTypeSignedChar
+.. py:data:: eBasicTypeUnsignedChar
+.. py:data:: eBasicTypeWChar
+.. py:data:: eBasicTypeSignedWChar
+.. py:data:: eBasicTypeUnsignedWChar
+.. py:data:: eBasicTypeChar16
+.. py:data:: eBasicTypeChar32
+.. py:data:: eBasicTypeShort
+.. py:data:: eBasicTypeUnsignedShort
+.. py:data:: eBasicTypeInt
+.. py:data:: eBasicTypeUnsignedInt
+.. py:data:: eBasicTypeLong
+.. py:data:: eBasicTypeUnsignedLong
+.. py:data:: eBasicTypeLongLong
+.. py:data:: eBasicTypeUnsignedLongLong
+.. py:data:: eBasicTypeInt128
+.. py:data:: eBasicTypeUnsignedInt128
+.. py:data:: eBasicTypeBool
+.. py:data:: eBasicTypeHalf
+.. py:data:: eBasicTypeFloat
+.. py:data:: eBasicTypeDouble
+.. py:data:: eBasicTypeLongDouble
+.. py:data:: eBasicTypeFloatComplex
+.. py:data:: eBasicTypeDoubleComplex
+.. py:data:: eBasicTypeLongDoubleComplex
+.. py:data:: eBasicTypeObjCID
+.. py:data:: eBasicTypeObjCClass
+.. py:data:: eBasicTypeObjCSel
+.. py:data:: eBasicTypeNullPtr
+.. py:data:: eBasicTypeOther
+
+TraceType
+---------
+
+.. py:data:: eTraceTypeNone
+.. py:data:: eTraceTypeProcessorTrace
+
+StructuredDataType
+------------------
+
+.. py:data:: eStructuredDataTypeInvalid
+.. py:data:: eStructuredDataTypeNull
+.. py:data:: eStructuredDataTypeGeneric
+.. py:data:: eStructuredDataTypeArray
+.. py:data:: eStructuredDataTypeInteger
+.. py:data:: eStructuredDataTypeFloat
+.. py:data:: eStructuredDataTypeBoolean
+.. py:data:: eStructuredDataTypeString
+.. py:data:: eStructuredDataTypeDictionary
+
+TypeClass
+---------
+
+.. py:data:: eTypeClassInvalid
+.. py:data:: eTypeClassArray
+.. py:data:: eTypeClassBlockPointer
+.. py:data:: eTypeClassBuiltin
+.. py:data:: eTypeClassClass
+.. py:data:: eTypeClassFloat
+.. py:data:: eTypeClassComplexInteger
+.. py:data:: eTypeClassComplexFloat
+.. py:data:: eTypeClassFunction
+.. py:data:: eTypeClassMemberPointer
+.. py:data:: eTypeClassObjCObject
+.. py:data:: eTypeClassObjCInterface
+.. py:data:: eTypeClassObjCObjectPointer
+.. py:data:: eTypeClassPointer
+.. py:data:: eTypeClassReference
+.. py:data:: eTypeClassStruct
+.. py:data:: eTypeClassTypedef
+.. py:data:: eTypeClassUnion
+.. py:data:: eTypeClassVector
+.. py:data:: eTypeClassOther
+.. py:data:: eTypeClassAny
+
+TemplateArgument
+----------------
+
+.. py:data:: eTemplateArgumentKindNull
+.. py:data:: eTemplateArgumentKindType
+.. py:data:: eTemplateArgumentKindDeclaration
+.. py:data:: eTemplateArgumentKindIntegral
+.. py:data:: eTemplateArgumentKindTemplate
+.. py:data:: eTemplateArgumentKindTemplateExpansion
+.. py:data:: eTemplateArgumentKindExpression
+.. py:data:: eTemplateArgumentKindPack
+.. py:data:: eTemplateArgumentKindNullPtr
+.. py:data:: eTemplateArgumentKindUncommonValue
+
+TypeOption
+----------
+
+Options that can be set for a formatter to alter its behavior. Not
+all of these are applicable to all formatter types.
+
+.. py:data:: eTypeOptionNone
+.. py:data:: eTypeOptionCascade
+.. py:data:: eTypeOptionSkipPointers
+.. py:data:: eTypeOptionSkipReferences
+.. py:data:: eTypeOptionHideChildren
+.. py:data:: eTypeOptionHideValue
+.. py:data:: eTypeOptionShowOneLiner
+.. py:data:: eTypeOptionHideNames
+.. py:data:: eTypeOptionNonCacheable
+.. py:data:: eTypeOptionHideEmptyAggregates
+.. py:data:: eTypeOptionFrontEndWantsDereference
+
+FrameCompare
+------------
+
+This is the return value for frame comparisons. If you are comparing frame
+A to frame B the following cases arise:
+
+ 1) When frame A pushes frame B (or a frame that ends up pushing
+ B) A is Older than B.
+
+ 2) When frame A pushed frame B (or if frameA is on the stack
+ but B is not) A is Younger than B.
+
+ 3) When frame A and frame B have the same StackID, they are
+ Equal.
+
+ 4) When frame A and frame B have the same immediate parent
+ frame, but are not equal, the comparison yields SameParent.
+
+ 5) If the two frames are on different threads or processes the
+ comparison is Invalid.
+
+ 6) If for some reason we can't figure out what went on, we
+ return Unknown.
+
+.. py:data:: eFrameCompareInvalid
+.. py:data:: eFrameCompareUnknown
+.. py:data:: eFrameCompareEqual
+.. py:data:: eFrameCompareSameParent
+.. py:data:: eFrameCompareYounger
+.. py:data:: eFrameCompareOlder
+
+FilePermissions
+---------------
+
+.. py:data:: eFilePermissionsUserRead
+.. py:data:: eFilePermissionsUserWrite
+.. py:data:: eFilePermissionsUserExecute
+.. py:data:: eFilePermissionsGroupRead
+.. py:data:: eFilePermissionsGroupWrite
+.. py:data:: eFilePermissionsGroupExecute
+.. py:data:: eFilePermissionsWorldRead
+.. py:data:: eFilePermissionsWorldWrite
+.. py:data:: eFilePermissionsWorldExecute
+.. py:data:: eFilePermissionsUserRW
+.. py:data:: eFileFilePermissionsUserRX
+.. py:data:: eFilePermissionsUserRWX
+.. py:data:: eFilePermissionsGroupRW
+.. py:data:: eFilePermissionsGroupRX
+.. py:data:: eFilePermissionsGroupRWX
+.. py:data:: eFilePermissionsWorldRW
+.. py:data:: eFilePermissionsWorldRX
+.. py:data:: eFilePermissionsWorldRWX
+.. py:data:: eFilePermissionsEveryoneR
+.. py:data:: eFilePermissionsEveryoneW
+.. py:data:: eFilePermissionsEveryoneX
+.. py:data:: eFilePermissionsEveryoneRW
+.. py:data:: eFilePermissionsEveryoneRX
+.. py:data:: eFilePermissionsEveryoneRWX
+.. py:data:: eFilePermissionsFileDefault = eFilePermissionsUserRW,
+.. py:data:: eFilePermissionsDirectoryDefault
+
+QueueItem
+---------
+.. py:data:: eQueueItemKindUnknown
+.. py:data:: eQueueItemKindFunction
+.. py:data:: eQueueItemKindBlock
+
+QueueKind
+---------
+
+libdispatch aka Grand Central Dispatch (GCD) queues can be either
+serial (executing on one thread) or concurrent (executing on
+multiple threads).
+
+.. py:data:: eQueueKindUnknown
+.. py:data:: eQueueKindSerial
+.. py:data:: eQueueKindConcurrent
+
+ExpressionEvaluationPhase
+-------------------------
+
+These are the cancellable stages of expression evaluation, passed
+to the expression evaluation callback, so that you can interrupt
+expression evaluation at the various points in its lifecycle.
+
+.. py:data:: eExpressionEvaluationParse
+.. py:data:: eExpressionEvaluationIRGen
+.. py:data:: eExpressionEvaluationExecution
+.. py:data:: eExpressionEvaluationComplete
+
+WatchpointKind
+--------------
+
+Indicates what types of events cause the watchpoint to fire. Used by Native
+-Protocol-related classes.
+
+.. py:data:: eWatchpointKindWrite
+.. py:data:: eWatchpointKindRead
+
+GdbSignal
+---------
+
+.. py:data:: eGdbSignalBadAccess
+.. py:data:: eGdbSignalBadInstruction
+.. py:data:: eGdbSignalArithmetic
+.. py:data:: eGdbSignalEmulation
+.. py:data:: eGdbSignalSoftware
+.. py:data:: eGdbSignalBreakpoint
+
+PathType
+--------
+
+Used with `SBHostOS.GetLLDBPath` to find files that are
+related to LLDB on the current host machine. Most files are
+relative to LLDB or are in known locations.
+
+.. py:data:: ePathTypeLLDBShlibDir
+
+ The directory where the lldb.so (unix) or LLDB mach-o file in
+ LLDB.framework (MacOSX) exists.
+
+.. py:data:: ePathTypeSupportExecutableDir
+
+ Find LLDB support executable directory (debugserver, etc).
+
+.. py:data:: ePathTypeHeaderDir
+
+ Find LLDB header file directory.
+
+.. py:data:: ePathTypePythonDir
+
+ Find Python modules (PYTHONPATH) directory.
+
+.. py:data:: ePathTypeLLDBSystemPlugins
+
+ System plug-ins directory
+
+.. py:data:: ePathTypeLLDBUserPlugins
+
+ User plug-ins directory
+
+.. py:data:: ePathTypeLLDBTempSystemDir
+
+ The LLDB temp directory for this system that will be cleaned up on exit.
+
+.. py:data:: ePathTypeGlobalLLDBTempSystemDir
+
+ The LLDB temp directory for this system, NOT cleaned up on a process
+ exit.
+
+.. py:data:: ePathTypeClangDir
+
+ Find path to Clang builtin headers.
+
+MemberFunctionKind
+------------------
+
+.. py:data:: eMemberFunctionKindUnknown
+.. py:data:: eMemberFunctionKindConstructor
+
+ A function used to create instances.
+
+.. py:data:: eMemberFunctionKindDestructor
+
+ A function used to tear down existing instances.
+
+.. py:data:: eMemberFunctionKindInstanceMethod
+
+ A function that applies to a specific instance.
+
+.. py:data:: eMemberFunctionKindStaticMethod
+
+ A function that applies to a type rather than any instance,
+
+TypeFlags
+---------
+
+.. py:data:: eTypeHasChildren
+.. py:data:: eTypeIsArray
+.. py:data:: eTypeIsBuiltIn
+.. py:data:: eTypeIsCPlusPlus
+.. py:data:: eTypeIsFuncPrototype
+.. py:data:: eTypeIsObjC
+.. py:data:: eTypeIsReference
+.. py:data:: eTypeIsTemplate
+.. py:data:: eTypeIsVector
+.. py:data:: eTypeIsInteger
+.. py:data:: eTypeIsComplex
+.. py:data:: eTypeInstanceIsPointer
+
+CommandFlags
+---------------
+
+.. py:data:: eCommandRequiresTarget
+.. py:data:: eCommandRequiresProcess
+.. py:data:: eCommandRequiresThread
+.. py:data:: eCommandRequiresFrame
+.. py:data:: eCommandRequiresRegContext
+.. py:data:: eCommandTryTargetAPILock
+.. py:data:: eCommandProcessMustBeLaunched
+.. py:data:: eCommandProcessMustBePaused
+.. py:data:: eCommandProcessMustBeTraced
+
+TypeSummary
+-----------
+
+Whether a summary should cap how much data it returns to users or not.
+
+.. py:data:: eTypeSummaryCapped
+.. py:data:: eTypeSummaryUncapped
+
+CommandInterpreterResult
+------------------------
+
+The result from a command interpreter run.
+
+.. py:data:: eCommandInterpreterResultSuccess
+
+ Command interpreter finished successfully.
+
+.. py:data:: eCommandInterpreterResultInferiorCrash
+
+ Stopped because the corresponding option was set and the inferior
+ crashed.
+
+.. py:data:: eCommandInterpreterResultCommandError
+
+ Stopped because the corresponding option was set and a command returned
+ an error.
+
+.. py:data:: eCommandInterpreterResultQuitRequested
+
+ Stopped because quit was requested.
diff --git a/contrib/llvm-project/lldb/include/lldb/API/LLDB.h b/contrib/llvm-project/lldb/include/lldb/API/LLDB.h
index 83c38d3b6166..f7390cfabf01 100644
--- a/contrib/llvm-project/lldb/include/lldb/API/LLDB.h
+++ b/contrib/llvm-project/lldb/include/lldb/API/LLDB.h
@@ -17,6 +17,7 @@
#include "lldb/API/SBBreakpointName.h"
#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBCommandInterpreter.h"
+#include "lldb/API/SBCommandInterpreterRunOptions.h"
#include "lldb/API/SBCommandReturnObject.h"
#include "lldb/API/SBCommunication.h"
#include "lldb/API/SBCompileUnit.h"
diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBAddress.h b/contrib/llvm-project/lldb/include/lldb/API/SBAddress.h
index cf7555dc2ee8..5a792a24cf6e 100644
--- a/contrib/llvm-project/lldb/include/lldb/API/SBAddress.h
+++ b/contrib/llvm-project/lldb/include/lldb/API/SBAddress.h
@@ -115,9 +115,9 @@ protected:
const lldb_private::Address &ref() const;
- SBAddress(const lldb_private::Address *lldb_object_ptr);
+ SBAddress(const lldb_private::Address &address);
- void SetAddress(const lldb_private::Address *lldb_object_ptr);
+ void SetAddress(const lldb_private::Address &address);
private:
std::unique_ptr<lldb_private::Address> m_opaque_up;
diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBBreakpoint.h b/contrib/llvm-project/lldb/include/lldb/API/SBBreakpoint.h
index c9a52fcacf1a..e13dbc5c3516 100644
--- a/contrib/llvm-project/lldb/include/lldb/API/SBBreakpoint.h
+++ b/contrib/llvm-project/lldb/include/lldb/API/SBBreakpoint.h
@@ -42,6 +42,8 @@ public:
void ClearAllBreakpointSites();
+ lldb::SBTarget GetTarget() const;
+
lldb::SBBreakpointLocation FindLocationByAddress(lldb::addr_t vm_addr);
lldb::break_id_t FindLocationIDByAddress(lldb::addr_t vm_addr);
@@ -140,7 +142,9 @@ public:
// Can only be called from a ScriptedBreakpointResolver...
SBError
AddLocation(SBAddress &address);
-
+
+ SBStructuredData SerializeToStructuredData();
+
private:
friend class SBBreakpointList;
friend class SBBreakpointLocation;
diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreter.h b/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreter.h
index a70e060bec99..2364a8dae88c 100644
--- a/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreter.h
+++ b/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreter.h
@@ -146,6 +146,8 @@ public:
const char *auto_repeat_command);
void SourceInitFileInHomeDirectory(lldb::SBCommandReturnObject &result);
+ void SourceInitFileInHomeDirectory(lldb::SBCommandReturnObject &result,
+ bool is_repl);
void
SourceInitFileInCurrentWorkingDirectory(lldb::SBCommandReturnObject &result);
diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h b/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h
index 82d6feedc02e..3c00513faaa7 100644
--- a/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h
+++ b/contrib/llvm-project/lldb/include/lldb/API/SBCommandInterpreterRunOptions.h
@@ -26,8 +26,12 @@ class LLDB_API SBCommandInterpreterRunOptions {
public:
SBCommandInterpreterRunOptions();
+ SBCommandInterpreterRunOptions(const SBCommandInterpreterRunOptions &rhs);
~SBCommandInterpreterRunOptions();
+ SBCommandInterpreterRunOptions &
+ operator=(const SBCommandInterpreterRunOptions &rhs);
+
bool GetStopOnContinue() const;
void SetStopOnContinue(bool);
diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBModule.h b/contrib/llvm-project/lldb/include/lldb/API/SBModule.h
index 859eaffe89a0..dd783fe4107d 100644
--- a/contrib/llvm-project/lldb/include/lldb/API/SBModule.h
+++ b/contrib/llvm-project/lldb/include/lldb/API/SBModule.h
@@ -291,12 +291,16 @@ public:
/// Get the number of global modules.
static uint32_t GetNumberAllocatedModules();
+ /// Remove any global modules which are no longer needed.
+ static void GarbageCollectAllocatedModules();
+
private:
friend class SBAddress;
friend class SBFrame;
friend class SBSection;
friend class SBSymbolContext;
friend class SBTarget;
+ friend class SBType;
explicit SBModule(const lldb::ModuleSP &module_sp);
diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBPlatform.h b/contrib/llvm-project/lldb/include/lldb/API/SBPlatform.h
index 4d251b129954..98291f18247d 100644
--- a/contrib/llvm-project/lldb/include/lldb/API/SBPlatform.h
+++ b/contrib/llvm-project/lldb/include/lldb/API/SBPlatform.h
@@ -51,6 +51,7 @@ protected:
class LLDB_API SBPlatformShellCommand {
public:
+ SBPlatformShellCommand(const char *shell, const char *shell_command);
SBPlatformShellCommand(const char *shell_command);
SBPlatformShellCommand(const SBPlatformShellCommand &rhs);
@@ -61,6 +62,10 @@ public:
void Clear();
+ const char *GetShell();
+
+ void SetShell(const char *shell);
+
const char *GetCommand();
void SetCommand(const char *shell_command);
diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBReproducer.h b/contrib/llvm-project/lldb/include/lldb/API/SBReproducer.h
index 78044e9acbc3..ecf28d6f0e11 100644
--- a/contrib/llvm-project/lldb/include/lldb/API/SBReproducer.h
+++ b/contrib/llvm-project/lldb/include/lldb/API/SBReproducer.h
@@ -11,8 +11,32 @@
#include "lldb/API/SBDefines.h"
+namespace lldb_private {
+namespace repro {
+struct ReplayOptions;
+}
+} // namespace lldb_private
+
namespace lldb {
+class LLDB_API SBReplayOptions {
+public:
+ SBReplayOptions();
+ SBReplayOptions(const SBReplayOptions &rhs);
+ ~SBReplayOptions();
+
+ SBReplayOptions &operator=(const SBReplayOptions &rhs);
+
+ void SetVerify(bool verify);
+ bool GetVerify() const;
+
+ void SetCheckVersion(bool check);
+ bool GetCheckVersion() const;
+
+private:
+ std::unique_ptr<lldb_private::repro::ReplayOptions> m_opaque_up;
+};
+
/// The SBReproducer class is special because it bootstraps the capture and
/// replay of SB API calls. As a result we cannot rely on any other SB objects
/// in the interface or implementation of this class.
@@ -22,7 +46,9 @@ public:
static const char *Capture(const char *path);
static const char *Replay(const char *path);
static const char *Replay(const char *path, bool skip_version_check);
+ static const char *Replay(const char *path, const SBReplayOptions &options);
static const char *PassiveReplay(const char *path);
+ static const char *Finalize(const char *path);
static const char *GetPath();
static bool SetAutoGenerate(bool b);
static bool Generate();
diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBTarget.h b/contrib/llvm-project/lldb/include/lldb/API/SBTarget.h
index fad842c9cb1c..30f4005dfc0f 100644
--- a/contrib/llvm-project/lldb/include/lldb/API/SBTarget.h
+++ b/contrib/llvm-project/lldb/include/lldb/API/SBTarget.h
@@ -560,6 +560,12 @@ public:
uint32_t column, lldb::addr_t offset,
SBFileSpecList &module_list);
+ lldb::SBBreakpoint
+ BreakpointCreateByLocation(const lldb::SBFileSpec &file_spec, uint32_t line,
+ uint32_t column, lldb::addr_t offset,
+ SBFileSpecList &module_list,
+ bool move_to_nearest_code);
+
lldb::SBBreakpoint BreakpointCreateByName(const char *symbol_name,
const char *module_name = nullptr);
diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBThreadPlan.h b/contrib/llvm-project/lldb/include/lldb/API/SBThreadPlan.h
index 8f16f4f5c4d2..0dc48437a668 100644
--- a/contrib/llvm-project/lldb/include/lldb/API/SBThreadPlan.h
+++ b/contrib/llvm-project/lldb/include/lldb/API/SBThreadPlan.h
@@ -77,6 +77,10 @@ public:
bool IsValid();
+ bool GetStopOthers();
+
+ void SetStopOthers(bool stop_others);
+
// This section allows an SBThreadPlan to push another of the common types of
// plans...
SBThreadPlan QueueThreadPlanForStepOverRange(SBAddress &start_address,
@@ -117,10 +121,11 @@ private:
friend class lldb_private::QueueImpl;
friend class SBQueueItem;
- lldb_private::ThreadPlan *get();
+ lldb::ThreadPlanSP GetSP() const { return m_opaque_wp.lock(); }
+ lldb_private::ThreadPlan *get() const { return GetSP().get(); }
void SetThreadPlan(const lldb::ThreadPlanSP &lldb_object_sp);
- lldb::ThreadPlanSP m_opaque_sp;
+ lldb::ThreadPlanWP m_opaque_wp;
};
} // namespace lldb
diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBType.h b/contrib/llvm-project/lldb/include/lldb/API/SBType.h
index b0af43351192..529b4d0eeffc 100644
--- a/contrib/llvm-project/lldb/include/lldb/API/SBType.h
+++ b/contrib/llvm-project/lldb/include/lldb/API/SBType.h
@@ -131,6 +131,8 @@ public:
bool IsAnonymousType();
+ bool IsScopedEnumerationType();
+
lldb::SBType GetPointerType();
lldb::SBType GetPointeeType();
@@ -150,6 +152,9 @@ public:
lldb::SBType GetVectorElementType();
lldb::SBType GetCanonicalType();
+
+ lldb::SBType GetEnumerationIntegerType();
+
// Get the "lldb::BasicType" enumeration for a type. If a type is not a basic
// type eBasicTypeInvalid will be returned
lldb::BasicType GetBasicType();
@@ -185,6 +190,8 @@ public:
lldb::SBTypeMemberFunction GetMemberFunctionAtIndex(uint32_t idx);
+ lldb::SBModule GetModule();
+
const char *GetName();
const char *GetDisplayTypeName();
diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h
index d29d21070fd7..ddb70b719d6e 100644
--- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h
+++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h
@@ -20,6 +20,7 @@
#include "lldb/Breakpoint/BreakpointName.h"
#include "lldb/Breakpoint/BreakpointOptions.h"
#include "lldb/Breakpoint/Stoppoint.h"
+#include "lldb/Breakpoint/StoppointHitCounter.h"
#include "lldb/Core/SearchFilter.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/StringList.h"
@@ -544,7 +545,7 @@ public:
/// if the condition says to stop and false otherwise.
///
void SetPrecondition(lldb::BreakpointPreconditionSP precondition_sp) {
- m_precondition_sp = precondition_sp;
+ m_precondition_sp = std::move(precondition_sp);
}
bool EvaluatePrecondition(StoppointCallbackContext &context);
@@ -624,13 +625,6 @@ protected:
bool IgnoreCountShouldStop();
- void IncrementHitCount() { m_hit_count++; }
-
- void DecrementHitCount() {
- assert(m_hit_count > 0);
- m_hit_count--;
- }
-
private:
// To call from CopyFromBreakpoint.
Breakpoint(Target &new_target, const Breakpoint &bp_to_copy_from);
@@ -660,10 +654,12 @@ private:
m_locations; // The list of locations currently found for this breakpoint.
std::string m_kind_description;
bool m_resolve_indirect_symbols;
- uint32_t m_hit_count; // Number of times this breakpoint/watchpoint has been
- // hit. This is kept
- // separately from the locations hit counts, since locations can go away when
- // their backing library gets unloaded, and we would lose hit counts.
+
+ /// Number of times this breakpoint has been hit. This is kept separately
+ /// from the locations hit counts, since locations can go away when their
+ /// backing library gets unloaded, and we would lose hit counts.
+ StoppointHitCounter m_hit_counter;
+
BreakpointName::Permissions m_permissions;
void SendBreakpointChangedEvent(lldb::BreakpointEventType eventKind);
diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocation.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocation.h
index 3fc571eaa292..4e1c57a40435 100644
--- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocation.h
+++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointLocation.h
@@ -13,7 +13,7 @@
#include <mutex>
#include "lldb/Breakpoint/BreakpointOptions.h"
-#include "lldb/Breakpoint/StoppointLocation.h"
+#include "lldb/Breakpoint/StoppointHitCounter.h"
#include "lldb/Core/Address.h"
#include "lldb/Utility/UserID.h"
#include "lldb/lldb-private.h"
@@ -35,15 +35,14 @@ namespace lldb_private {
/// be useful if you've set options on the locations.
class BreakpointLocation
- : public std::enable_shared_from_this<BreakpointLocation>,
- public StoppointLocation {
+ : public std::enable_shared_from_this<BreakpointLocation> {
public:
- ~BreakpointLocation() override;
+ ~BreakpointLocation();
/// Gets the load address for this breakpoint location \return
/// Returns breakpoint location load address, \b
/// LLDB_INVALID_ADDRESS if not yet set.
- lldb::addr_t GetLoadAddress() const override;
+ lldb::addr_t GetLoadAddress() const;
/// Gets the Address for this breakpoint location \return
/// Returns breakpoint location Address.
@@ -63,7 +62,7 @@ public:
/// \return
/// \b true if this breakpoint location thinks we should stop,
/// \b false otherwise.
- bool ShouldStop(StoppointCallbackContext *context) override;
+ bool ShouldStop(StoppointCallbackContext *context);
// The next section deals with various breakpoint options.
@@ -85,11 +84,14 @@ public:
/// \b true if the breakpoint is set to auto-continue, \b false if not.
bool IsAutoContinue() const;
+ /// Return the current Hit Count.
+ uint32_t GetHitCount() const { return m_hit_counter.GetValue(); }
+
/// Return the current Ignore Count.
///
/// \return
/// The number of breakpoint hits to be ignored.
- uint32_t GetIgnoreCount();
+ uint32_t GetIgnoreCount() const;
/// Set the breakpoint to ignore the next \a count breakpoint hits.
///
@@ -192,7 +194,7 @@ public:
void GetDescription(Stream *s, lldb::DescriptionLevel level);
/// Standard "Dump" method. At present it does nothing.
- void Dump(Stream *s) const override;
+ void Dump(Stream *s) const;
/// Use this to set location specific breakpoint options.
///
@@ -268,6 +270,9 @@ public:
/// \b true or \b false as given in the description above.
bool EquivalentToLocation(BreakpointLocation &location);
+ /// Returns the breakpoint location ID.
+ lldb::break_id_t GetID() const { return m_loc_id; }
+
protected:
friend class BreakpointSite;
friend class BreakpointLocationList;
@@ -338,6 +343,9 @@ private:
/// multiple processes.
size_t m_condition_hash; ///< For testing whether the condition source code
///changed.
+ lldb::break_id_t m_loc_id; ///< Breakpoint location ID.
+ StoppointHitCounter m_hit_counter; ///< Number of times this breakpoint
+ /// location has been hit.
void SetShouldResolveIndirectFunctions(bool do_resolve) {
m_should_resolve_indirect_functions = do_resolve;
diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h
index 615b4eb77be4..85b8e025a8e5 100644
--- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h
+++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointOptions.h
@@ -51,7 +51,7 @@ public:
: user_source(user_source), script_source(), interpreter(interp),
stop_on_error(true) {}
- ~CommandData() = default;
+ virtual ~CommandData() = default;
static const char *GetSerializationKey() { return "BKPTCMDData"; }
diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointSite.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointSite.h
index 5ce17f511db4..fc32c04ffe35 100644
--- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointSite.h
+++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/BreakpointSite.h
@@ -14,7 +14,8 @@
#include "lldb/Breakpoint/BreakpointLocationCollection.h"
-#include "lldb/Breakpoint/StoppointLocation.h"
+#include "lldb/Breakpoint/StoppointSite.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/UserID.h"
#include "lldb/lldb-forward.h"
@@ -32,7 +33,7 @@ namespace lldb_private {
/// by the process.
class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>,
- public StoppointLocation {
+ public StoppointSite {
public:
enum Type {
eSoftware, // Breakpoint opcode has been written to memory and
@@ -60,8 +61,6 @@ public:
/// Sets the trap opcode
bool SetTrapOpcode(const uint8_t *trap_opcode, uint32_t trap_opcode_size);
- void SetHardwareIndex(uint32_t index) override;
-
/// Gets the original instruction bytes that were overwritten by the trap
uint8_t *GetSavedOpcodeBytes();
@@ -184,6 +183,12 @@ public:
/// \b false otherwise.
bool IsInternal() const;
+ bool IsHardware() const override {
+ lldbassert(BreakpointSite::Type::eHardware == GetType() ||
+ !HardwareRequired());
+ return BreakpointSite::Type::eHardware == GetType();
+ }
+
BreakpointSite::Type GetType() const { return m_type; }
void SetType(BreakpointSite::Type type) { m_type = type; }
diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointHitCounter.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointHitCounter.h
new file mode 100644
index 000000000000..26f816da6430
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointHitCounter.h
@@ -0,0 +1,43 @@
+//===-- StoppointHitCounter.h -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_BREAKPOINT_STOPPOINT_HIT_COUNTER_H
+#define LLDB_BREAKPOINT_STOPPOINT_HIT_COUNTER_H
+
+#include <assert.h>
+#include <cstdint>
+#include <limits>
+
+#include "lldb/Utility/LLDBAssert.h"
+
+namespace lldb_private {
+
+class StoppointHitCounter {
+public:
+ uint32_t GetValue() const { return m_hit_count; }
+
+ void Increment(uint32_t difference = 1) {
+ lldbassert(std::numeric_limits<uint32_t>::max() - m_hit_count >= difference);
+ m_hit_count += difference;
+ }
+
+ void Decrement(uint32_t difference = 1) {
+ lldbassert(m_hit_count >= difference);
+ m_hit_count -= difference;
+ }
+
+ void Reset() { m_hit_count = 0; }
+
+private:
+ /// Number of times this breakpoint/watchpoint has been hit.
+ uint32_t m_hit_count = 0;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_BREAKPOINT_STOPPOINT_HIT_COUNTER_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointLocation.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointLocation.h
deleted file mode 100644
index 4d6ca044ccc4..000000000000
--- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointLocation.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//===-- StoppointLocation.h -------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_BREAKPOINT_STOPPOINTLOCATION_H
-#define LLDB_BREAKPOINT_STOPPOINTLOCATION_H
-
-#include "lldb/Utility/UserID.h"
-#include "lldb/lldb-private.h"
-// #include "lldb/Breakpoint/BreakpointOptions.h"
-
-namespace lldb_private {
-
-class StoppointLocation {
-public:
- // Constructors and Destructors
- StoppointLocation(lldb::break_id_t bid, lldb::addr_t m_addr, bool hardware);
-
- StoppointLocation(lldb::break_id_t bid, lldb::addr_t m_addr,
- uint32_t byte_size, bool hardware);
-
- virtual ~StoppointLocation();
-
- // Operators
-
- // Methods
- virtual lldb::addr_t GetLoadAddress() const { return m_addr; }
-
- virtual void SetLoadAddress(lldb::addr_t addr) { m_addr = addr; }
-
- uint32_t GetByteSize() const { return m_byte_size; }
-
- uint32_t GetHitCount() const { return m_hit_count; }
-
- uint32_t GetHardwareIndex() const { return m_hardware_index; }
-
- bool HardwareRequired() const { return m_hardware; }
-
- virtual bool IsHardware() const {
- return m_hardware_index != LLDB_INVALID_INDEX32;
- }
-
- virtual bool ShouldStop(StoppointCallbackContext *context) { return true; }
-
- virtual void Dump(Stream *stream) const {}
-
- virtual void SetHardwareIndex(uint32_t index) { m_hardware_index = index; }
-
- lldb::break_id_t GetID() const { return m_loc_id; }
-
-protected:
- // Classes that inherit from StoppointLocation can see and modify these
- lldb::break_id_t m_loc_id; // Stoppoint location ID
- lldb::addr_t
- m_addr; // The load address of this stop point. The base Stoppoint doesn't
- // store a full Address since that's not needed for the breakpoint sites.
- bool m_hardware; // True if this point has been is required to use hardware
- // (which may fail due to lack of resources)
- uint32_t m_hardware_index; // The hardware resource index for this
- // breakpoint/watchpoint
- uint32_t m_byte_size; // The size in bytes of stop location. e.g. the length
- // of the trap opcode for
- // software breakpoints, or the optional length in bytes for hardware
- // breakpoints, or the length of the watchpoint.
- uint32_t
- m_hit_count; // Number of times this breakpoint/watchpoint has been hit
-
- // If you override this, be sure to call the base class to increment the
- // internal counter.
- void IncrementHitCount() { ++m_hit_count; }
-
- void DecrementHitCount();
-
-private:
- // For StoppointLocation only
- StoppointLocation(const StoppointLocation &) = delete;
- const StoppointLocation &operator=(const StoppointLocation &) = delete;
- StoppointLocation() = delete;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_BREAKPOINT_STOPPOINTLOCATION_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointSite.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointSite.h
new file mode 100644
index 000000000000..7e5e33486345
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/StoppointSite.h
@@ -0,0 +1,81 @@
+//===-- StoppointSite.h -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_BREAKPOINT_STOPPOINTSITE_H
+#define LLDB_BREAKPOINT_STOPPOINTSITE_H
+
+#include "lldb/Breakpoint/StoppointHitCounter.h"
+#include "lldb/Utility/UserID.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class StoppointSite {
+public:
+ StoppointSite(lldb::break_id_t bid, lldb::addr_t m_addr, bool hardware);
+
+ StoppointSite(lldb::break_id_t bid, lldb::addr_t m_addr,
+ uint32_t byte_size, bool hardware);
+
+ virtual ~StoppointSite() = default;
+
+ virtual lldb::addr_t GetLoadAddress() const { return m_addr; }
+
+ virtual void SetLoadAddress(lldb::addr_t addr) { m_addr = addr; }
+
+ uint32_t GetByteSize() const { return m_byte_size; }
+
+ uint32_t GetHitCount() const { return m_hit_counter.GetValue(); }
+
+ void ResetHitCount() { m_hit_counter.Reset(); }
+
+ bool HardwareRequired() const { return m_is_hardware_required; }
+
+ virtual bool IsHardware() const = 0;
+
+ uint32_t GetHardwareIndex() const { return m_hardware_index; }
+
+ void SetHardwareIndex(uint32_t index) { m_hardware_index = index; }
+
+ virtual bool ShouldStop(StoppointCallbackContext* context) = 0;
+
+ virtual void Dump(Stream* stream) const = 0;
+
+ lldb::break_id_t GetID() const { return m_id; }
+
+protected:
+ /// Stoppoint site ID.
+ lldb::break_id_t m_id;
+
+ /// The load address of this stop point.
+ lldb::addr_t m_addr;
+
+ /// True if this point is required to use hardware (which may fail due to
+ /// the lack of resources).
+ bool m_is_hardware_required;
+
+ /// The hardware resource index for this breakpoint/watchpoint.
+ uint32_t m_hardware_index;
+
+ /// The size in bytes of stoppoint, e.g. the length of the trap opcode for
+ /// software breakpoints, or the optional length in bytes for hardware
+ /// breakpoints, or the length of the watchpoint.
+ uint32_t m_byte_size;
+
+ /// Number of times this breakpoint/watchpoint has been hit.
+ StoppointHitCounter m_hit_counter;
+
+private:
+ StoppointSite(const StoppointSite &) = delete;
+ const StoppointSite &operator=(const StoppointSite &) = delete;
+ StoppointSite() = delete;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_BREAKPOINT_STOPPOINTSITE_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/Watchpoint.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/Watchpoint.h
index bce15f0a85dd..41b723a66b6a 100644
--- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/Watchpoint.h
+++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/Watchpoint.h
@@ -12,7 +12,7 @@
#include <memory>
#include <string>
-#include "lldb/Breakpoint/StoppointLocation.h"
+#include "lldb/Breakpoint/StoppointSite.h"
#include "lldb/Breakpoint/WatchpointOptions.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Target.h"
@@ -22,7 +22,7 @@
namespace lldb_private {
class Watchpoint : public std::enable_shared_from_this<Watchpoint>,
- public StoppointLocation {
+ public StoppointSite {
public:
class WatchpointEventData : public EventData {
public:
@@ -158,8 +158,6 @@ private:
friend class Target;
friend class WatchpointList;
- void ResetHitCount() { m_hit_count = 0; }
-
void ResetHistoricValues() {
m_old_value_sp.reset();
m_new_value_sp.reset();
@@ -199,7 +197,7 @@ private:
std::unique_ptr<UserExpression> m_condition_up; // The condition to test.
- void SetID(lldb::watch_id_t id) { m_loc_id = id; }
+ void SetID(lldb::watch_id_t id) { m_id = id; }
void SendWatchpointChangedEvent(lldb::WatchpointEventType eventKind);
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Architecture.h b/contrib/llvm-project/lldb/include/lldb/Core/Architecture.h
index d8dbbb4f540f..2ea8bd31ebf4 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/Architecture.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Architecture.h
@@ -15,9 +15,6 @@ namespace lldb_private {
class Architecture : public PluginInterface {
public:
- Architecture() = default;
- ~Architecture() override = default;
-
/// This is currently intended to handle cases where a
/// program stops at an instruction that won't get executed and it
/// allows the stop reason, like "breakpoint hit", to be replaced
@@ -100,10 +97,6 @@ public:
Target &target) const {
return addr;
}
-
-private:
- Architecture(const Architecture &) = delete;
- void operator=(const Architecture &) = delete;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Communication.h b/contrib/llvm-project/lldb/include/lldb/Core/Communication.h
index 6b65974f9522..354c4bbcc283 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/Communication.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Communication.h
@@ -285,7 +285,7 @@ public:
///
void SynchronizeWithReadThread();
- static const char *ConnectionStatusAsCString(lldb::ConnectionStatus status);
+ static std::string ConnectionStatusAsString(lldb::ConnectionStatus status);
bool GetCloseOnEOF() const { return m_close_on_eof; }
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h b/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h
index 7bea0dbae082..68daae1a3710 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h
@@ -273,6 +273,8 @@ public:
bool SetUseColor(bool use_color);
+ bool GetUseAutosuggestion() const;
+
bool GetUseSourceCache() const;
bool SetUseSourceCache(bool use_source_cache);
@@ -332,8 +334,8 @@ public:
// This is for use in the command interpreter, when you either want the
// selected target, or if no target 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() { return m_dummy_target_sp.get(); }
+ Target &GetSelectedOrDummyTarget(bool prefer_dummy = false);
+ Target &GetDummyTarget() { return *m_dummy_target_sp; }
lldb::BroadcasterManagerSP GetBroadcasterManager() {
return m_broadcaster_manager_sp;
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h b/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h
index 926a74b933ef..9a694de0f60a 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h
@@ -48,6 +48,7 @@ class DataExtractor;
class Debugger;
class Disassembler;
class Module;
+class StackFrame;
class Stream;
class SymbolContext;
class SymbolContextList;
@@ -270,6 +271,13 @@ public:
lldb::InstructionSP GetInstructionAtIndex(size_t idx) const;
+ /// Get the instruction at the given address.
+ ///
+ /// \return
+ /// A valid \a InstructionSP if the address could be found, or null
+ /// otherwise.
+ lldb::InstructionSP GetInstructionAtAddress(const Address &addr);
+
//------------------------------------------------------------------
/// Get the index of the next branch instruction.
///
@@ -279,9 +287,6 @@ public:
/// @param[in] start
/// The instruction index of the first instruction to check.
///
- /// @param[in] target
- /// A LLDB target object that is used to resolve addresses.
- ///
/// @param[in] ignore_calls
/// It true, then fine the first branch instruction that isn't
/// a function call (a branch that calls and returns to the next
@@ -298,7 +303,6 @@ public:
/// found.
//------------------------------------------------------------------
uint32_t GetIndexOfNextBranchInstruction(uint32_t start,
- Target &target,
bool ignore_calls,
bool *found_calls) const;
@@ -408,11 +412,8 @@ public:
uint32_t num_mixed_context_lines, uint32_t options,
Stream &strm);
- static bool
- Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name,
- const char *flavor, const ExecutionContext &exe_ctx,
- uint32_t num_instructions, bool mixed_source_and_assembly,
- uint32_t num_mixed_context_lines, uint32_t options, Stream &strm);
+ static bool Disassemble(Debugger &debugger, const ArchSpec &arch,
+ StackFrame &frame, Stream &strm);
// Constructors and Destructors
Disassembler(const ArchSpec &arch, const char *flavor);
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h b/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h
index 51592afbbabe..2e8f3225fd5f 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h
@@ -15,7 +15,6 @@
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Flags.h"
#include "lldb/Utility/Predicate.h"
-#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StringList.h"
#include "lldb/lldb-defines.h"
@@ -32,6 +31,9 @@
namespace lldb_private {
class Debugger;
+namespace repro {
+class DataRecorder;
+}
}
namespace curses {
@@ -126,11 +128,11 @@ public:
FILE *GetErrorFILE();
- lldb::FileSP &GetInputFileSP();
+ lldb::FileSP GetInputFileSP();
- lldb::StreamFileSP &GetOutputStreamFileSP();
+ lldb::StreamFileSP GetOutputStreamFileSP();
- lldb::StreamFileSP &GetErrorStreamFileSP();
+ lldb::StreamFileSP GetErrorStreamFileSP();
Debugger &GetDebugger() { return m_debugger; }
@@ -203,6 +205,9 @@ public:
virtual void IOHandlerDeactivated(IOHandler &io_handler) {}
+ virtual llvm::Optional<std::string> IOHandlerSuggestion(IOHandler &io_handler,
+ llvm::StringRef line);
+
virtual void IOHandlerComplete(IOHandler &io_handler,
CompletionRequest &request);
@@ -420,6 +425,9 @@ private:
static int FixIndentationCallback(Editline *editline, const StringList &lines,
int cursor_position, void *baton);
+ static llvm::Optional<std::string> SuggestionCallback(llvm::StringRef line,
+ void *baton);
+
static void AutoCompleteCallback(CompletionRequest &request, void *baton);
#endif
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/IOHandlerCursesGUI.h b/contrib/llvm-project/lldb/include/lldb/Core/IOHandlerCursesGUI.h
index fe62eaea643e..22ca735063ba 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/IOHandlerCursesGUI.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/IOHandlerCursesGUI.h
@@ -31,6 +31,8 @@ public:
void Deactivate() override;
+ void TerminalSizeChanged() override;
+
protected:
curses::ApplicationAP m_app_ap;
};
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Module.h b/contrib/llvm-project/lldb/include/lldb/Core/Module.h
index 8bd70ab16b5a..9eb7477730c1 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/Module.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Module.h
@@ -506,10 +506,6 @@ public:
return m_object_mod_time;
}
- void SetObjectModificationTime(const llvm::sys::TimePoint<> &mod_time) {
- m_mod_time = mod_time;
- }
-
/// This callback will be called by SymbolFile implementations when
/// parsing a compile unit that contains SDK information.
/// \param sysroot will be added to the path remapping dictionary.
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h b/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h
index d90b27e474ac..46a718f08f04 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h
@@ -56,7 +56,7 @@ public:
ModuleListProperties();
FileSpec GetClangModulesCachePath() const;
- bool SetClangModulesCachePath(llvm::StringRef path);
+ bool SetClangModulesCachePath(const FileSpec &path);
bool GetEnableExternalLookup() const;
bool SetEnableExternalLookup(bool new_value);
@@ -237,20 +237,6 @@ public:
/// \see ModuleList::GetSize()
Module *GetModulePointerAtIndex(size_t idx) const;
- /// Get the module pointer for the module at index \a idx without acquiring
- /// the ModuleList mutex. This MUST already have been acquired with
- /// ModuleList::GetMutex and locked for this call to be safe.
- ///
- /// \param[in] idx
- /// An index into this module collection.
- ///
- /// \return
- /// A pointer to a Module which can by nullptr if \a idx is out
- /// of range.
- ///
- /// \see ModuleList::GetSize()
- Module *GetModulePointerAtIndexUnlocked(size_t idx) const;
-
/// Find compile units by partial or full path.
///
/// Finds all compile units that match \a path in all of the modules and
@@ -491,11 +477,13 @@ public:
typedef LockingAdaptedIterable<collection, lldb::ModuleSP, vector_adapter,
std::recursive_mutex>
ModuleIterable;
- ModuleIterable Modules() { return ModuleIterable(m_modules, GetMutex()); }
+ ModuleIterable Modules() const {
+ return ModuleIterable(m_modules, GetMutex());
+ }
typedef AdaptedIterable<collection, lldb::ModuleSP, vector_adapter>
ModuleIterableNoLocking;
- ModuleIterableNoLocking ModulesNoLocking() {
+ ModuleIterableNoLocking ModulesNoLocking() const {
return ModuleIterableNoLocking(m_modules);
}
};
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h b/contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h
index 17f6dc367155..5bdb2f45b665 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h
@@ -15,11 +15,15 @@ namespace lldb_private {
class PluginInterface {
public:
- virtual ~PluginInterface() {}
+ PluginInterface() = default;
+ virtual ~PluginInterface() = default;
virtual ConstString GetPluginName() = 0;
virtual uint32_t GetPluginVersion() = 0;
+
+ PluginInterface(const PluginInterface &) = delete;
+ PluginInterface &operator=(const PluginInterface &) = delete;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h b/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h
index 5e0c9395dae0..0ac8308d1758 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h
@@ -330,6 +330,42 @@ public:
static SymbolVendorCreateInstance
GetSymbolVendorCreateCallbackAtIndex(uint32_t idx);
+ // Trace
+ static bool RegisterPlugin(ConstString name, const char *description,
+ TraceCreateInstance create_callback,
+ llvm::StringRef schema,
+ TraceGetStartCommand get_start_command);
+
+ static bool UnregisterPlugin(TraceCreateInstance create_callback);
+
+ static TraceCreateInstance GetTraceCreateCallback(ConstString plugin_name);
+
+ static lldb::CommandObjectSP
+ GetTraceStartCommand(llvm::StringRef plugin_name,
+ CommandInterpreter &interpreter);
+
+ /// Get the JSON schema for a trace session file corresponding to the given
+ /// plugin.
+ ///
+ /// \param[in] plugin_name
+ /// The name of the plugin.
+ ///
+ /// \return
+ /// An empty \a StringRef if no plugin was found with that plugin name,
+ /// otherwise the actual schema is returned.
+ static llvm::StringRef GetTraceSchema(ConstString plugin_name);
+
+ /// Get the JSON schema for a trace session file corresponding to the plugin
+ /// given by its index.
+ ///
+ /// \param[in] index
+ /// The index of the plugin to get the schema of.
+ ///
+ /// \return
+ /// An empty \a StringRef if the index is greater than or equal to the
+ /// number plugins, otherwise the actual schema is returned.
+ static llvm::StringRef GetTraceSchema(size_t index);
+
// UnwindAssembly
static bool RegisterPlugin(ConstString name, const char *description,
UnwindAssemblyCreateInstance create_callback);
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h b/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h
index 9aea645a3ea6..929ce21fb2f9 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h
@@ -68,14 +68,18 @@ public:
return error;
}
- // Grab the plugin.
- auto plugin_sp = lldb::StructuredDataPluginSP(m_plugin_wp);
+ // Grab the plugin
+ lldb::StructuredDataPluginSP plugin_sp = m_plugin_wp.lock();
+
+ // If there's no plugin, call underlying data's dump method:
if (!plugin_sp) {
- error.SetErrorString("Cannot pretty print structured data: "
- "plugin doesn't exist.");
+ if (!m_data_sp) {
+ error.SetErrorString("No data to describe.");
+ return error;
+ }
+ m_data_sp->Dump(stream, true);
return error;
}
-
// Get the data's description.
return plugin_sp->GetDescription(m_data_sp, stream);
}
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Value.h b/contrib/llvm-project/lldb/include/lldb/Core/Value.h
index 641a64a3bbbe..0ff773e59911 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/Value.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Value.h
@@ -43,8 +43,6 @@ public:
// m_value contains...
// ============================
eValueTypeScalar, // raw scalar value
- eValueTypeVector, // byte array of m_vector.length with endianness of
- // m_vector.byte_order
eValueTypeFileAddress, // file address value
eValueTypeLoadAddress, // load address value
eValueTypeHostAddress // host address value (for memory in the process that
@@ -62,66 +60,8 @@ public:
eContextTypeVariable // lldb_private::Variable *
};
- const static size_t kMaxByteSize = 32u;
-
- struct Vector {
- // The byte array must be big enough to hold vector registers for any
- // supported target.
- uint8_t bytes[kMaxByteSize];
- size_t length;
- lldb::ByteOrder byte_order;
-
- Vector() : length(0), byte_order(lldb::eByteOrderInvalid) {}
-
- Vector(const Vector &vector) { *this = vector; }
- const Vector &operator=(const Vector &vector) {
- SetBytes(vector.bytes, vector.length, vector.byte_order);
- return *this;
- }
-
- void Clear() { length = 0; }
-
- bool SetBytes(const void *bytes, size_t length,
- lldb::ByteOrder byte_order) {
- this->length = length;
- this->byte_order = byte_order;
- if (length)
- ::memcpy(this->bytes, bytes,
- length < kMaxByteSize ? length : kMaxByteSize);
- return IsValid();
- }
-
- bool IsValid() const {
- return (length > 0 && length < kMaxByteSize &&
- byte_order != lldb::eByteOrderInvalid);
- }
- // Casts a vector, if valid, to an unsigned int of matching or largest
- // supported size. Truncates to the beginning of the vector if required.
- // Returns a default constructed Scalar if the Vector data is internally
- // inconsistent.
- llvm::APInt rhs = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
- ((type128 *)bytes)->x);
- Scalar GetAsScalar() const {
- Scalar scalar;
- if (IsValid()) {
- if (length == 1)
- scalar = *(const uint8_t *)bytes;
- else if (length == 2)
- scalar = *(const uint16_t *)bytes;
- else if (length == 4)
- scalar = *(const uint32_t *)bytes;
- else if (length == 8)
- scalar = *(const uint64_t *)bytes;
- else if (length >= 16)
- scalar = rhs;
- }
- return scalar;
- }
- };
-
Value();
Value(const Scalar &scalar);
- Value(const Vector &vector);
Value(const void *bytes, int len);
Value(const Value &rhs);
@@ -153,8 +93,7 @@ public:
m_context = p;
if (m_context_type == eContextTypeRegisterInfo) {
RegisterInfo *reg_info = GetRegisterInfo();
- if (reg_info->encoding == lldb::eEncodingVector &&
- m_vector.byte_order != lldb::eByteOrderInvalid)
+ if (reg_info->encoding == lldb::eEncodingVector)
SetValueType(eValueTypeScalar);
}
}
@@ -167,30 +106,8 @@ public:
const Scalar &GetScalar() const { return m_value; }
- const Vector &GetVector() const { return m_vector; }
-
Scalar &GetScalar() { return m_value; }
- Vector &GetVector() { return m_vector; }
-
- bool SetVectorBytes(const Vector &vector) {
- m_vector = vector;
- return m_vector.IsValid();
- }
-
- bool SetVectorBytes(uint8_t *bytes, size_t length,
- lldb::ByteOrder byte_order) {
- return m_vector.SetBytes(bytes, length, byte_order);
- }
-
- bool SetScalarFromVector() {
- if (m_vector.IsValid()) {
- m_value = m_vector.GetAsScalar();
- return true;
- }
- return false;
- }
-
size_t ResizeData(size_t len);
size_t AppendDataToHostBuffer(const Value &rhs);
@@ -225,7 +142,6 @@ public:
protected:
Scalar m_value;
- Vector m_vector;
CompilerType m_compiler_type;
void *m_context;
ValueType m_value_type;
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h
index 0080368fd996..a665e7afa0ca 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h
@@ -358,7 +358,7 @@ public:
virtual bool CanProvideValue();
// Subclasses must implement the functions below.
- virtual uint64_t GetByteSize() = 0;
+ virtual llvm::Optional<uint64_t> GetByteSize() = 0;
virtual lldb::ValueType GetValueType() const = 0;
@@ -702,12 +702,12 @@ public:
}
void SetSummaryFormat(lldb::TypeSummaryImplSP format) {
- m_type_summary_sp = format;
+ m_type_summary_sp = std::move(format);
ClearUserVisibleData(eClearUserVisibleDataItemsSummary);
}
void SetValueFormat(lldb::TypeFormatImplSP format) {
- m_type_format_sp = format;
+ m_type_format_sp = std::move(format);
ClearUserVisibleData(eClearUserVisibleDataItemsValue);
}
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h
index d91ca6a92be8..342803f8ca63 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h
@@ -30,7 +30,7 @@ public:
ConstString name,
const CompilerType &cast_type);
- uint64_t GetByteSize() override;
+ llvm::Optional<uint64_t> GetByteSize() override;
size_t CalculateNumChildren(uint32_t max) override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h
index c6f44a29b059..9a9fd9294261 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h
@@ -30,7 +30,7 @@ class ValueObjectChild : public ValueObject {
public:
~ValueObjectChild() override;
- uint64_t GetByteSize() override { return m_byte_size; }
+ llvm::Optional<uint64_t> GetByteSize() override { return m_byte_size; }
lldb::offset_t GetByteOffset() override { return m_byte_offset; }
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h
index 0e868c687e93..8d823baa0b7b 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h
@@ -62,7 +62,7 @@ public:
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
const Status &error);
- uint64_t GetByteSize() override;
+ llvm::Optional<uint64_t> GetByteSize() override;
lldb::ValueType GetValueType() const override;
@@ -113,7 +113,7 @@ protected:
CompilerType GetCompilerTypeImpl() override;
ConstString m_type_name;
- uint64_t m_byte_size;
+ llvm::Optional<uint64_t> m_byte_size;
ValueObjectConstResultImpl m_impl;
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h
index 9f5304b55e93..2806857339ef 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h
@@ -34,7 +34,7 @@ class ValueObjectDynamicValue : public ValueObject {
public:
~ValueObjectDynamicValue() override;
- uint64_t GetByteSize() override;
+ llvm::Optional<uint64_t> GetByteSize() override;
ConstString GetTypeName() override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h
index d1cd6ae41445..b5d5e6ecf4c0 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h
@@ -40,7 +40,7 @@ public:
const Address &address,
const CompilerType &ast_type);
- uint64_t GetByteSize() override;
+ llvm::Optional<uint64_t> GetByteSize() override;
ConstString GetTypeName() override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h
index 41051d93b707..3968584ad518 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h
@@ -36,7 +36,7 @@ public:
lldb::RegisterContextSP &reg_ctx_sp,
uint32_t set_idx);
- uint64_t GetByteSize() override;
+ llvm::Optional<uint64_t> GetByteSize() override;
lldb::ValueType GetValueType() const override {
return lldb::eValueTypeRegisterSet;
@@ -86,7 +86,7 @@ public:
lldb::RegisterContextSP &reg_ctx_sp,
uint32_t reg_num);
- uint64_t GetByteSize() override;
+ llvm::Optional<uint64_t> GetByteSize() override;
lldb::ValueType GetValueType() const override {
return lldb::eValueTypeRegister;
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h
index cb471657aec9..41c461ce13f0 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h
@@ -36,7 +36,7 @@ class ValueObjectSynthetic : public ValueObject {
public:
~ValueObjectSynthetic() override;
- uint64_t GetByteSize() override;
+ llvm::Optional<uint64_t> GetByteSize() override;
ConstString GetTypeName() override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h
index b7e262574a14..23fdedbf5a4a 100644
--- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h
@@ -37,7 +37,7 @@ public:
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
const lldb::VariableSP &var_sp);
- uint64_t GetByteSize() override;
+ llvm::Optional<uint64_t> GetByteSize() override;
ConstString GetTypeName() override;
diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/DataVisualization.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/DataVisualization.h
index b053aa074d9e..7be07d65acdd 100644
--- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/DataVisualization.h
+++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/DataVisualization.h
@@ -69,9 +69,9 @@ public:
static void Clear();
- static void
- ForEach(std::function<bool(ConstString, const lldb::TypeSummaryImplSP &)>
- callback);
+ static void ForEach(std::function<bool(const TypeMatcher &,
+ const lldb::TypeSummaryImplSP &)>
+ callback);
static uint32_t GetCount();
};
diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormatManager.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormatManager.h
index 56a0303f9b02..978ad148d6c4 100644
--- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormatManager.h
+++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormatManager.h
@@ -34,7 +34,7 @@ namespace lldb_private {
// this file's objects directly
class FormatManager : public IFormatChangeListener {
- typedef FormatMap<ConstString, TypeSummaryImpl> NamedSummariesMap;
+ typedef FormattersContainer<TypeSummaryImpl> NamedSummariesMap;
typedef TypeCategoryMap::MapType::iterator CategoryMapIterator;
public:
@@ -144,13 +144,6 @@ public:
static const char *GetFormatAsCString(lldb::Format format);
- // if the user tries to add formatters for, say, "struct Foo" those will not
- // match any type because of the way we strip qualifiers from typenames this
- // method looks for the case where the user is adding a
- // "class","struct","enum" or "union" Foo and strips the unnecessary
- // qualifier
- static ConstString GetValidTypeName(ConstString type);
-
// when DataExtractor dumps a vectorOfT, it uses a predefined format for each
// item this method returns it, or eFormatInvalid if vector_format is not a
// vectorOf
diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersContainer.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersContainer.h
index d414882bae19..2f56218c43a7 100644
--- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersContainer.h
+++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersContainer.h
@@ -37,57 +37,103 @@ public:
virtual uint32_t GetCurrentRevision() = 0;
};
-// if the user tries to add formatters for, say, "struct Foo" those will not
-// match any type because of the way we strip qualifiers from typenames this
-// method looks for the case where the user is adding a "class","struct","enum"
-// or "union" Foo and strips the unnecessary qualifier
-static inline ConstString GetValidTypeName_Impl(ConstString type) {
- if (type.IsEmpty())
- return type;
+/// Class for matching type names.
+class TypeMatcher {
+ RegularExpression m_type_name_regex;
+ ConstString m_type_name;
+ /// False if m_type_name_regex should be used for matching. False if this is
+ /// just matching by comparing with m_type_name string.
+ bool m_is_regex;
- std::string type_cstr(type.AsCString());
- StringLexer type_lexer(type_cstr);
+ // if the user tries to add formatters for, say, "struct Foo" those will not
+ // match any type because of the way we strip qualifiers from typenames this
+ // method looks for the case where the user is adding a
+ // "class","struct","enum" or "union" Foo and strips the unnecessary qualifier
+ static ConstString StripTypeName(ConstString type) {
+ if (type.IsEmpty())
+ return type;
- type_lexer.AdvanceIf("class ");
- type_lexer.AdvanceIf("enum ");
- type_lexer.AdvanceIf("struct ");
- type_lexer.AdvanceIf("union ");
+ std::string type_cstr(type.AsCString());
+ StringLexer type_lexer(type_cstr);
- while (type_lexer.NextIf({' ', '\t', '\v', '\f'}).first)
- ;
+ type_lexer.AdvanceIf("class ");
+ type_lexer.AdvanceIf("enum ");
+ type_lexer.AdvanceIf("struct ");
+ type_lexer.AdvanceIf("union ");
- return ConstString(type_lexer.GetUnlexed());
-}
+ while (type_lexer.NextIf({' ', '\t', '\v', '\f'}).first)
+ ;
-template <typename KeyType, typename ValueType> class FormattersContainer;
+ return ConstString(type_lexer.GetUnlexed());
+ }
-template <typename KeyType, typename ValueType> class FormatMap {
public:
- typedef typename ValueType::SharedPointer ValueSP;
- typedef std::vector<std::pair<KeyType, ValueSP>> MapType;
- typedef typename MapType::iterator MapIterator;
- typedef std::function<bool(const KeyType &, const ValueSP &)> ForEachCallback;
+ TypeMatcher() = delete;
+ /// Creates a matcher that accepts any type with exactly the given type name.
+ TypeMatcher(ConstString type_name)
+ : m_type_name(type_name), m_is_regex(false) {}
+ /// Creates a matcher that accepts any type matching the given regex.
+ TypeMatcher(RegularExpression regex)
+ : m_type_name_regex(std::move(regex)), m_is_regex(true) {}
+
+ /// True iff this matches the given type name.
+ bool Matches(ConstString type_name) const {
+ if (m_is_regex)
+ return m_type_name_regex.Execute(type_name.GetStringRef());
+ return m_type_name == type_name ||
+ StripTypeName(m_type_name) == StripTypeName(type_name);
+ }
+
+ /// Returns the underlying match string for this TypeMatcher.
+ ConstString GetMatchString() const {
+ if (m_is_regex)
+ return ConstString(m_type_name_regex.GetText());
+ return StripTypeName(m_type_name);
+ }
+
+ /// Returns true if this TypeMatcher and the given one were most created by
+ /// the same match string.
+ /// The main purpose of this function is to find existing TypeMatcher
+ /// instances by the user input that created them. This is necessary as LLDB
+ /// allows referencing existing TypeMatchers in commands by the user input
+ /// that originally created them:
+ /// (lldb) type summary add --summary-string \"A\" -x TypeName
+ /// (lldb) type summary delete TypeName
+ bool CreatedBySameMatchString(TypeMatcher other) const {
+ return GetMatchString() == other.GetMatchString();
+ }
+};
+
+template <typename ValueType> class FormattersContainer {
+public:
+ typedef typename std::shared_ptr<ValueType> ValueSP;
+ typedef std::vector<std::pair<TypeMatcher, ValueSP>> MapType;
+ typedef std::function<bool(const TypeMatcher &, const ValueSP &)>
+ ForEachCallback;
+ typedef typename std::shared_ptr<FormattersContainer<ValueType>>
+ SharedPointer;
+
+ friend class TypeCategoryImpl;
- FormatMap(IFormatChangeListener *lst)
- : m_map(), m_map_mutex(), listener(lst) {}
+ FormattersContainer(IFormatChangeListener *lst) : listener(lst) {}
- void Add(KeyType name, const ValueSP &entry) {
+ void Add(TypeMatcher matcher, const ValueSP &entry) {
if (listener)
entry->GetRevision() = listener->GetCurrentRevision();
else
entry->GetRevision() = 0;
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
- Delete(name);
- m_map.emplace_back(std::move(name), std::move(entry));
+ Delete(matcher);
+ m_map.emplace_back(std::move(matcher), std::move(entry));
if (listener)
listener->Changed();
}
- bool Delete(const KeyType &name) {
+ bool Delete(TypeMatcher matcher) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
- for (MapIterator iter = m_map.begin(); iter != m_map.end(); ++iter)
- if (iter->first == name) {
+ for (auto iter = m_map.begin(); iter != m_map.end(); ++iter)
+ if (iter->first.CreatedBySameMatchString(matcher)) {
m_map.erase(iter);
if (listener)
listener->Changed();
@@ -96,217 +142,78 @@ public:
return false;
}
- void Clear() {
+ bool Get(ConstString type, ValueSP &entry) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
- m_map.clear();
- if (listener)
- listener->Changed();
+ for (auto &formatter : llvm::reverse(m_map)) {
+ if (formatter.first.Matches(type)) {
+ entry = formatter.second;
+ return true;
+ }
+ }
+ return false;
}
- bool Get(const KeyType &name, ValueSP &entry) {
+ bool GetExact(TypeMatcher matcher, ValueSP &entry) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
for (const auto &pos : m_map)
- if (pos.first == name) {
+ if (pos.first.CreatedBySameMatchString(matcher)) {
entry = pos.second;
return true;
}
return false;
}
- void ForEach(ForEachCallback callback) {
- if (callback) {
- std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
- for (const auto &pos : m_map) {
- const KeyType &type = pos.first;
- if (!callback(type, pos.second))
- break;
- }
- }
- }
-
- uint32_t GetCount() { return m_map.size(); }
-
- ValueSP GetValueAtIndex(size_t index) {
+ ValueSP GetAtIndex(size_t index) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
if (index >= m_map.size())
return ValueSP();
return m_map[index].second;
}
- // If caller holds the mutex we could return a reference without copy ctor.
- KeyType GetKeyAtIndex(size_t index) {
+ lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierAtIndex(size_t index) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
if (index >= m_map.size())
- return {};
- return m_map[index].first;
- }
-
-protected:
- MapType m_map;
- std::recursive_mutex m_map_mutex;
- IFormatChangeListener *listener;
-
- MapType &map() { return m_map; }
-
- std::recursive_mutex &mutex() { return m_map_mutex; }
-
- friend class FormattersContainer<KeyType, ValueType>;
- friend class FormatManager;
-};
-
-template <typename KeyType, typename ValueType> class FormattersContainer {
-protected:
- typedef FormatMap<KeyType, ValueType> BackEndType;
-
-public:
- typedef typename BackEndType::MapType MapType;
- typedef typename MapType::iterator MapIterator;
- typedef KeyType MapKeyType;
- typedef std::shared_ptr<ValueType> MapValueType;
- typedef typename BackEndType::ForEachCallback ForEachCallback;
- typedef typename std::shared_ptr<FormattersContainer<KeyType, ValueType>>
- SharedPointer;
-
- friend class TypeCategoryImpl;
-
- FormattersContainer(std::string name, IFormatChangeListener *lst)
- : m_format_map(lst), m_name(name) {}
-
- void Add(MapKeyType type, const MapValueType &entry) {
- Add_Impl(std::move(type), entry, static_cast<KeyType *>(nullptr));
- }
-
- bool Delete(ConstString type) {
- return Delete_Impl(type, static_cast<KeyType *>(nullptr));
- }
-
- bool Get(ValueObject &valobj, MapValueType &entry,
- lldb::DynamicValueType use_dynamic) {
- CompilerType ast_type(valobj.GetCompilerType());
- bool ret = Get(valobj, ast_type, entry, use_dynamic);
- if (ret)
- entry = MapValueType(entry);
- else
- entry = MapValueType();
- return ret;
+ return lldb::TypeNameSpecifierImplSP();
+ TypeMatcher type_matcher = m_map[index].first;
+ return std::make_shared<TypeNameSpecifierImpl>(
+ type_matcher.GetMatchString().GetStringRef(), true);
}
- bool Get(ConstString type, MapValueType &entry) {
- return Get_Impl(type, entry, static_cast<KeyType *>(nullptr));
+ void Clear() {
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
+ m_map.clear();
+ if (listener)
+ listener->Changed();
}
- bool GetExact(ConstString type, MapValueType &entry) {
- return GetExact_Impl(type, entry, static_cast<KeyType *>(nullptr));
+ void ForEach(ForEachCallback callback) {
+ if (callback) {
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
+ for (const auto &pos : m_map) {
+ const TypeMatcher &type = pos.first;
+ if (!callback(type, pos.second))
+ break;
+ }
+ }
}
- MapValueType GetAtIndex(size_t index) {
- return m_format_map.GetValueAtIndex(index);
+ uint32_t GetCount() {
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
+ return m_map.size();
}
- lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierAtIndex(size_t index) {
- return GetTypeNameSpecifierAtIndex_Impl(index,
- static_cast<KeyType *>(nullptr));
+ void AutoComplete(CompletionRequest &request) {
+ ForEach([&request](const TypeMatcher &matcher, const ValueSP &value) {
+ request.TryCompleteCurrentArg(matcher.GetMatchString().GetStringRef());
+ return true;
+ });
}
- void Clear() { m_format_map.Clear(); }
-
- void ForEach(ForEachCallback callback) { m_format_map.ForEach(callback); }
-
- uint32_t GetCount() { return m_format_map.GetCount(); }
-
protected:
- BackEndType m_format_map;
- std::string m_name;
-
FormattersContainer(const FormattersContainer &) = delete;
const FormattersContainer &operator=(const FormattersContainer &) = delete;
- void Add_Impl(MapKeyType type, const MapValueType &entry,
- RegularExpression *dummy) {
- m_format_map.Add(std::move(type), entry);
- }
-
- void Add_Impl(ConstString type, const MapValueType &entry,
- ConstString *dummy) {
- m_format_map.Add(GetValidTypeName_Impl(type), entry);
- }
-
- bool Delete_Impl(ConstString type, ConstString *dummy) {
- return m_format_map.Delete(type);
- }
-
- bool Delete_Impl(ConstString type, RegularExpression *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++) {
- const RegularExpression &regex = pos->first;
- if (type.GetStringRef() == regex.GetText()) {
- 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) {
- return m_format_map.Get(type, entry);
- }
-
- bool GetExact_Impl(ConstString type, MapValueType &entry,
- ConstString *dummy) {
- return Get_Impl(type, entry, static_cast<KeyType *>(nullptr));
- }
-
- lldb::TypeNameSpecifierImplSP
- GetTypeNameSpecifierAtIndex_Impl(size_t index, ConstString *dummy) {
- ConstString key = m_format_map.GetKeyAtIndex(index);
- if (key)
- return lldb::TypeNameSpecifierImplSP(
- new TypeNameSpecifierImpl(key.GetStringRef(), false));
- else
- return lldb::TypeNameSpecifierImplSP();
- }
-
- lldb::TypeNameSpecifierImplSP
- GetTypeNameSpecifierAtIndex_Impl(size_t index, RegularExpression *dummy) {
- RegularExpression regex = m_format_map.GetKeyAtIndex(index);
- if (regex == RegularExpression())
- return lldb::TypeNameSpecifierImplSP();
- return lldb::TypeNameSpecifierImplSP(
- new TypeNameSpecifierImpl(regex.GetText().str().c_str(), true));
- }
-
- bool Get_Impl(ConstString key, MapValueType &value,
- RegularExpression *dummy) {
- llvm::StringRef key_str = key.GetStringRef();
- std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex());
- // Patterns are matched in reverse-chronological order.
- for (const auto &pos : llvm::reverse(m_format_map.map())) {
- const RegularExpression &regex = pos.first;
- if (regex.Execute(key_str)) {
- value = pos.second;
- return true;
- }
- }
- return false;
- }
-
- bool GetExact_Impl(ConstString key, MapValueType &value,
- RegularExpression *dummy) {
- std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex());
- for (const auto &pos : m_format_map.map()) {
- const RegularExpression &regex = pos.first;
- if (regex.GetText() == key.GetStringRef()) {
- value = pos.second;
- return true;
- }
- }
- return false;
- }
-
- bool Get(const FormattersMatchVector &candidates, MapValueType &entry) {
+ bool Get(const FormattersMatchVector &candidates, ValueSP &entry) {
for (const FormattersMatchCandidate &candidate : candidates) {
if (Get(candidate.GetTypeName(), entry)) {
if (candidate.IsMatch(entry) == false) {
@@ -319,6 +226,10 @@ protected:
}
return false;
}
+
+ MapType m_map;
+ std::recursive_mutex m_map_mutex;
+ IFormatChangeListener *listener;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/StringPrinter.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/StringPrinter.h
index 17c645f8637a..4a6e2e9051bf 100644
--- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/StringPrinter.h
+++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/StringPrinter.h
@@ -109,7 +109,7 @@ public:
uint64_t GetLocation() const { return m_location; }
- void SetProcessSP(lldb::ProcessSP p) { m_process_sp = p; }
+ void SetProcessSP(lldb::ProcessSP p) { m_process_sp = std::move(p); }
lldb::ProcessSP GetProcessSP() const { return m_process_sp; }
diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategory.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategory.h
index 820872a59bda..2c9305901837 100644
--- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategory.h
+++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategory.h
@@ -25,14 +25,13 @@ namespace lldb_private {
template <typename FormatterImpl> class FormatterContainerPair {
public:
- typedef FormattersContainer<ConstString, FormatterImpl> ExactMatchContainer;
- typedef FormattersContainer<RegularExpression, FormatterImpl>
- RegexMatchContainer;
+ typedef FormattersContainer<FormatterImpl> ExactMatchContainer;
+ typedef FormattersContainer<FormatterImpl> RegexMatchContainer;
- typedef typename ExactMatchContainer::MapType ExactMatchMap;
- typedef typename RegexMatchContainer::MapType RegexMatchMap;
+ typedef TypeMatcher ExactMatchMap;
+ typedef TypeMatcher RegexMatchMap;
- typedef typename ExactMatchContainer::MapValueType MapValueType;
+ typedef typename ExactMatchContainer::ValueSP MapValueType;
typedef typename ExactMatchContainer::SharedPointer ExactMatchContainerSP;
typedef typename RegexMatchContainer::SharedPointer RegexMatchContainerSP;
@@ -42,10 +41,9 @@ public:
typedef
typename RegexMatchContainer::ForEachCallback RegexMatchForEachCallback;
- FormatterContainerPair(const char *exact_name, const char *regex_name,
- IFormatChangeListener *clist)
- : m_exact_sp(new ExactMatchContainer(std::string(exact_name), clist)),
- m_regex_sp(new RegexMatchContainer(std::string(regex_name), clist)) {}
+ FormatterContainerPair(IFormatChangeListener *clist)
+ : m_exact_sp(new ExactMatchContainer(clist)),
+ m_regex_sp(new RegexMatchContainer(clist)) {}
~FormatterContainerPair() = default;
@@ -93,52 +91,52 @@ public:
template <typename U = TypeFormatImpl>
typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
SetExact(FormatContainer::ExactMatchForEachCallback callback) {
- m_format_exact = callback;
+ m_format_exact = std::move(callback);
return *this;
}
template <typename U = TypeFormatImpl>
typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
SetWithRegex(FormatContainer::RegexMatchForEachCallback callback) {
- m_format_regex = callback;
+ m_format_regex = std::move(callback);
return *this;
}
template <typename U = TypeSummaryImpl>
typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
SetExact(SummaryContainer::ExactMatchForEachCallback callback) {
- m_summary_exact = callback;
+ m_summary_exact = std::move(callback);
return *this;
}
template <typename U = TypeSummaryImpl>
typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
SetWithRegex(SummaryContainer::RegexMatchForEachCallback callback) {
- m_summary_regex = callback;
+ m_summary_regex = std::move(callback);
return *this;
}
template <typename U = TypeFilterImpl>
typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
SetExact(FilterContainer::ExactMatchForEachCallback callback) {
- m_filter_exact = callback;
+ m_filter_exact = std::move(callback);
return *this;
}
template <typename U = TypeFilterImpl>
typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
SetWithRegex(FilterContainer::RegexMatchForEachCallback callback) {
- m_filter_regex = callback;
+ m_filter_regex = std::move(callback);
return *this;
}
template <typename U = SyntheticChildren>
typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
SetExact(SynthContainer::ExactMatchForEachCallback callback) {
- m_synth_exact = callback;
+ m_synth_exact = std::move(callback);
return *this;
}
template <typename U = SyntheticChildren>
typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
SetWithRegex(SynthContainer::RegexMatchForEachCallback callback) {
- m_synth_regex = callback;
+ m_synth_regex = std::move(callback);
return *this;
}
@@ -349,19 +347,13 @@ private:
friend class LanguageCategory;
friend class TypeCategoryMap;
- friend class FormattersContainer<ConstString, TypeFormatImpl>;
- friend class FormattersContainer<lldb::RegularExpressionSP, TypeFormatImpl>;
+ friend class FormattersContainer<TypeFormatImpl>;
- friend class FormattersContainer<ConstString, TypeSummaryImpl>;
- friend class FormattersContainer<lldb::RegularExpressionSP, TypeSummaryImpl>;
+ friend class FormattersContainer<TypeSummaryImpl>;
- friend class FormattersContainer<ConstString, TypeFilterImpl>;
- friend class FormattersContainer<lldb::RegularExpressionSP, TypeFilterImpl>;
-
- friend class FormattersContainer<ConstString, ScriptedSyntheticChildren>;
- friend class FormattersContainer<lldb::RegularExpressionSP,
- ScriptedSyntheticChildren>;
+ friend class FormattersContainer<TypeFilterImpl>;
+ friend class FormattersContainer<ScriptedSyntheticChildren>;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategoryMap.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategoryMap.h
index 832652f7d745..4dbca29db066 100644
--- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategoryMap.h
+++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeCategoryMap.h
@@ -84,7 +84,8 @@ private:
lldb::TypeCategoryImplSP ptr;
public:
- delete_matching_categories(lldb::TypeCategoryImplSP p) : ptr(p) {}
+ delete_matching_categories(lldb::TypeCategoryImplSP p)
+ : ptr(std::move(p)) {}
bool operator()(const lldb::TypeCategoryImplSP &other) {
return ptr.get() == other.get();
@@ -103,7 +104,7 @@ private:
std::recursive_mutex &mutex() { return m_map_mutex; }
- friend class FormattersContainer<KeyType, ValueType>;
+ friend class FormattersContainer<ValueType>;
friend class FormatManager;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSummary.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSummary.h
index 6c3780f7276d..ce3195dbb693 100644
--- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSummary.h
+++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSummary.h
@@ -322,7 +322,7 @@ struct CXXFunctionSummaryFormat : public TypeSummaryImpl {
const char *GetTextualInfo() const { return m_description.c_str(); }
- void SetBackendFunction(Callback cb_func) { m_impl = cb_func; }
+ void SetBackendFunction(Callback cb_func) { m_impl = std::move(cb_func); }
void SetTextualInfo(const char *descr) {
if (descr)
diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSynthetic.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSynthetic.h
index c852ff18bfa2..fa1458281f1e 100644
--- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSynthetic.h
+++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/TypeSynthetic.h
@@ -362,7 +362,7 @@ public:
CreateFrontEndCallback;
CXXSyntheticChildren(const SyntheticChildren::Flags &flags,
const char *description, CreateFrontEndCallback callback)
- : SyntheticChildren(flags), m_create_callback(callback),
+ : SyntheticChildren(flags), m_create_callback(std::move(callback)),
m_description(description ? description : "") {}
bool IsScripted() override { return false; }
diff --git a/contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h b/contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h
index 6b63b186e3e4..c7d4e4b1882f 100644
--- a/contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h
+++ b/contrib/llvm-project/lldb/include/lldb/Expression/DWARFExpression.h
@@ -219,6 +219,10 @@ public:
bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op);
+ llvm::Optional<DataExtractor>
+ GetLocationExpression(lldb::addr_t load_function_start,
+ lldb::addr_t addr) const;
+
private:
/// Pretty-prints the location expression to a stream
///
@@ -237,10 +241,6 @@ private:
void DumpLocation(Stream *s, const DataExtractor &data,
lldb::DescriptionLevel level, ABI *abi) const;
- llvm::Optional<DataExtractor>
- GetLocationExpression(lldb::addr_t load_function_start,
- lldb::addr_t addr) const;
-
/// Module which defined this expression.
lldb::ModuleWP m_module_wp;
diff --git a/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionVariable.h b/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionVariable.h
index 60062d212bad..4259e6395da4 100644
--- a/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionVariable.h
+++ b/contrib/llvm-project/lldb/include/lldb/Expression/ExpressionVariable.h
@@ -32,7 +32,7 @@ public:
virtual ~ExpressionVariable();
- size_t GetByteSize() { return m_frozen_sp->GetByteSize(); }
+ llvm::Optional<uint64_t> GetByteSize() { return m_frozen_sp->GetByteSize(); }
ConstString GetName() { return m_frozen_sp->GetName(); }
diff --git a/contrib/llvm-project/lldb/include/lldb/Expression/UtilityFunction.h b/contrib/llvm-project/lldb/include/lldb/Expression/UtilityFunction.h
index 5ebbc0ede1e3..99fb32153aa2 100644
--- a/contrib/llvm-project/lldb/include/lldb/Expression/UtilityFunction.h
+++ b/contrib/llvm-project/lldb/include/lldb/Expression/UtilityFunction.h
@@ -42,8 +42,8 @@ public:
///
/// \param[in] name
/// The name of the function, as used in the text.
- UtilityFunction(ExecutionContextScope &exe_scope, const char *text,
- const char *name);
+ UtilityFunction(ExecutionContextScope &exe_scope, std::string text,
+ std::string name);
~UtilityFunction() override;
@@ -110,9 +110,10 @@ public:
protected:
std::shared_ptr<IRExecutionUnit> m_execution_unit_sp;
lldb::ModuleWP m_jit_module_wp;
- std::string m_function_text; ///< The text of the function. Must be a
- ///well-formed translation unit.
- std::string m_function_name; ///< The name of the function.
+ /// The text of the function. Must be a well-formed translation unit.
+ std::string m_function_text;
+ /// The name of the function.
+ std::string m_function_name;
std::unique_ptr<FunctionCaller> m_caller_up;
};
diff --git a/contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake b/contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake
index 42f4ca1a26c6..c667708a90a6 100644
--- a/contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake
+++ b/contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake
@@ -20,6 +20,8 @@
#cmakedefine01 HAVE_PPOLL
+#cmakedefine01 HAVE_PTSNAME_R
+
#cmakedefine01 HAVE_SIGACTION
#cmakedefine01 HAVE_PROCESS_VM_READV
@@ -38,6 +40,8 @@
#cmakedefine01 LLDB_ENABLE_CURSES
+#cmakedefine01 CURSES_HAVE_NCURSES_CURSES_H
+
#cmakedefine01 LLDB_ENABLE_LIBEDIT
#cmakedefine01 LLDB_ENABLE_LIBXML2
@@ -48,7 +52,7 @@
#cmakedefine01 LLDB_EMBED_PYTHON_HOME
-#cmakedefine LLDB_PYTHON_HOME "${LLDB_PYTHON_HOME}"
+#cmakedefine LLDB_PYTHON_HOME R"(${LLDB_PYTHON_HOME})"
#define LLDB_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}"
diff --git a/contrib/llvm-project/lldb/include/lldb/Host/Editline.h b/contrib/llvm-project/lldb/include/lldb/Host/Editline.h
index 356e8f734732..a37ad1b9d106 100644
--- a/contrib/llvm-project/lldb/include/lldb/Host/Editline.h
+++ b/contrib/llvm-project/lldb/include/lldb/Host/Editline.h
@@ -98,6 +98,9 @@ typedef int (*FixIndentationCallbackType)(Editline *editline,
const StringList &lines,
int cursor_position, void *baton);
+typedef llvm::Optional<std::string> (*SuggestionCallbackType)(
+ llvm::StringRef line, void *baton);
+
typedef void (*CompleteCallbackType)(CompletionRequest &request, void *baton);
/// Status used to decide when and how to start editing another line in
@@ -184,6 +187,9 @@ public:
/// Cancel this edit and oblitarate all trace of it
bool Cancel();
+ /// Register a callback for autosuggestion.
+ void SetSuggestionCallback(SuggestionCallbackType callback, void *baton);
+
/// Register a callback for the tab key
void SetAutoCompleteCallback(CompleteCallbackType callback, void *baton);
@@ -312,6 +318,12 @@ private:
/// tab key is typed.
unsigned char TabCommand(int ch);
+ /// Apply autosuggestion part in gray as editline.
+ unsigned char ApplyAutosuggestCommand(int ch);
+
+ /// Command used when a character is typed.
+ unsigned char TypedCharacter(int ch);
+
/// Respond to normal character insertion by fixing line indentation
unsigned char FixIndentationCommand(int ch);
@@ -360,7 +372,9 @@ private:
const char *m_fix_indentation_callback_chars = nullptr;
CompleteCallbackType m_completion_callback = nullptr;
void *m_completion_callback_baton = nullptr;
-
+ SuggestionCallbackType m_suggestion_callback = nullptr;
+ void *m_suggestion_callback_baton = nullptr;
+ std::size_t m_previous_autosuggestion_size = 0;
std::mutex m_output_mutex;
};
}
diff --git a/contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h b/contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h
index 8dcff3402592..02ff5f301336 100644
--- a/contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h
+++ b/contrib/llvm-project/lldb/include/lldb/Host/FileSystem.h
@@ -33,13 +33,14 @@ public:
FileSystem()
: m_fs(llvm::vfs::getRealFileSystem()), m_collector(nullptr),
- m_mapped(false) {}
- FileSystem(std::shared_ptr<llvm::FileCollector> collector)
- : m_fs(llvm::vfs::getRealFileSystem()), m_collector(collector),
- m_mapped(false) {}
+ m_home_directory(), m_mapped(false) {}
+ FileSystem(std::shared_ptr<llvm::FileCollectorBase> collector)
+ : m_fs(llvm::vfs::getRealFileSystem()), m_collector(std::move(collector)),
+ m_home_directory(), m_mapped(false) {}
FileSystem(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs,
bool mapped = false)
- : m_fs(fs), m_collector(nullptr), m_mapped(mapped) {}
+ : m_fs(std::move(fs)), m_collector(nullptr), m_home_directory(),
+ m_mapped(mapped) {}
FileSystem(const FileSystem &fs) = delete;
FileSystem &operator=(const FileSystem &fs) = delete;
@@ -47,7 +48,7 @@ public:
static FileSystem &Instance();
static void Initialize();
- static void Initialize(std::shared_ptr<llvm::FileCollector> collector);
+ static void Initialize(std::shared_ptr<llvm::FileCollectorBase> collector);
static llvm::Error Initialize(const FileSpec &mapping);
static void Initialize(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs);
static void Terminate();
@@ -154,6 +155,10 @@ public:
/// Call into the Host to see if it can help find the file.
bool ResolveExecutableLocation(FileSpec &file_spec);
+ /// Get the user home directory.
+ bool GetHomeDirectory(llvm::SmallVectorImpl<char> &path) const;
+ bool GetHomeDirectory(FileSpec &file_spec) const;
+
enum EnumerateDirectoryResult {
/// Enumerate next entry in the current directory.
eEnumerateDirectoryResultNext,
@@ -189,10 +194,13 @@ public:
void Collect(const FileSpec &file_spec);
void Collect(const llvm::Twine &file);
+ void SetHomeDirectory(std::string home_directory);
+
private:
static llvm::Optional<FileSystem> &InstanceImpl();
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> m_fs;
- std::shared_ptr<llvm::FileCollector> m_collector;
+ std::shared_ptr<llvm::FileCollectorBase> m_collector;
+ std::string m_home_directory;
bool m_mapped;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/Host/Host.h b/contrib/llvm-project/lldb/include/lldb/Host/Host.h
index f19cb85d2329..76792cc6eab5 100644
--- a/contrib/llvm-project/lldb/include/lldb/Host/Host.h
+++ b/contrib/llvm-project/lldb/include/lldb/Host/Host.h
@@ -196,19 +196,34 @@ public:
static Status ShellExpandArguments(ProcessLaunchInfo &launch_info);
/// Run a shell command.
- /// \arg command shouldn't be NULL
+ /// \arg command shouldn't be empty
/// \arg working_dir Pass empty FileSpec to use the current working directory
/// \arg status_ptr Pass NULL if you don't want the process exit status
/// \arg signo_ptr Pass NULL if you don't want the signal that caused the
/// process to exit
/// \arg command_output Pass NULL if you don't want the command output
/// \arg hide_stderr if this is false, redirect stderr to stdout
- /// TODO: Convert this function to take a StringRef.
- static Status RunShellCommand(const char *command,
+ static Status RunShellCommand(llvm::StringRef command,
const FileSpec &working_dir, int *status_ptr,
int *signo_ptr, std::string *command_output,
const Timeout<std::micro> &timeout,
- bool run_in_default_shell = true,
+ bool run_in_shell = true,
+ bool hide_stderr = false);
+
+ /// Run a shell command.
+ /// \arg shell Pass an empty string if you want to use the default shell
+ /// interpreter \arg command \arg working_dir Pass empty FileSpec to use the
+ /// current working directory \arg status_ptr Pass NULL if you don't want
+ /// the process exit status \arg signo_ptr Pass NULL if you don't want the
+ /// signal that caused
+ /// the process to exit
+ /// \arg command_output Pass NULL if you don't want the command output
+ /// \arg hide_stderr If this is \b false, redirect stderr to stdout
+ static Status RunShellCommand(llvm::StringRef shell, llvm::StringRef command,
+ const FileSpec &working_dir, int *status_ptr,
+ int *signo_ptr, std::string *command_output,
+ const Timeout<std::micro> &timeout,
+ bool run_in_shell = true,
bool hide_stderr = false);
/// Run a shell command.
@@ -222,7 +237,23 @@ public:
int *status_ptr, int *signo_ptr,
std::string *command_output,
const Timeout<std::micro> &timeout,
- bool run_in_default_shell = true,
+ bool run_in_shell = true,
+ bool hide_stderr = false);
+
+ /// Run a shell command.
+ /// \arg shell Pass an empty string if you want to use the default
+ /// shell interpreter \arg command \arg working_dir Pass empty FileSpec to use
+ /// the current working directory \arg status_ptr Pass NULL if you don't
+ /// want the process exit status \arg signo_ptr Pass NULL if you don't
+ /// want the signal that caused the
+ /// process to exit
+ /// \arg command_output Pass NULL if you don't want the command output
+ /// \arg hide_stderr If this is \b false, redirect stderr to stdout
+ static Status RunShellCommand(llvm::StringRef shell, const Args &args,
+ const FileSpec &working_dir, int *status_ptr,
+ int *signo_ptr, std::string *command_output,
+ const Timeout<std::micro> &timeout,
+ bool run_in_shell = true,
bool hide_stderr = false);
static bool OpenFileInExternalEditor(const FileSpec &file_spec,
diff --git a/contrib/llvm-project/lldb/include/lldb/Host/HostInfoBase.h b/contrib/llvm-project/lldb/include/lldb/Host/HostInfoBase.h
index 70682c9b685e..15bb168aad97 100644
--- a/contrib/llvm-project/lldb/include/lldb/Host/HostInfoBase.h
+++ b/contrib/llvm-project/lldb/include/lldb/Host/HostInfoBase.h
@@ -11,6 +11,7 @@
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/UUID.h"
#include "lldb/Utility/UserIDResolver.h"
#include "lldb/Utility/XcodeSDK.h"
#include "lldb/lldb-enumerations.h"
@@ -24,6 +25,11 @@ namespace lldb_private {
class FileSpec;
+struct SharedCacheImageInfo {
+ UUID uuid;
+ lldb::DataBufferSP data_sp;
+};
+
class HostInfoBase {
private:
// Static class, unconstructable.
@@ -98,6 +104,13 @@ public:
/// Return the directory containing a specific Xcode SDK.
static llvm::StringRef GetXcodeSDKPath(XcodeSDK sdk) { return {}; }
+ /// Return information about module \p image_name if it is loaded in
+ /// the current process's address space.
+ static SharedCacheImageInfo
+ GetSharedCacheImageInfo(llvm::StringRef image_name) {
+ return {};
+ }
+
protected:
static bool ComputeSharedLibraryDirectory(FileSpec &file_spec);
static bool ComputeSupportExeDirectory(FileSpec &file_spec);
diff --git a/contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h b/contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h
index e83d8396e9f2..ee9755580825 100644
--- a/contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h
+++ b/contrib/llvm-project/lldb/include/lldb/Host/ProcessLaunchInfo.h
@@ -94,10 +94,9 @@ public:
void Clear();
- bool ConvertArgumentsForLaunchingInShell(Status &error, bool localhost,
- bool will_debug,
+ bool ConvertArgumentsForLaunchingInShell(Status &error, bool will_debug,
bool first_arg_is_full_shell_command,
- int32_t num_resumes);
+ uint32_t num_resumes);
void
SetMonitorProcessCallback(const Host::MonitorChildProcessCallback &callback,
diff --git a/contrib/llvm-project/lldb/include/lldb/Host/PseudoTerminal.h b/contrib/llvm-project/lldb/include/lldb/Host/PseudoTerminal.h
index 8a5a233e7748..350f926dcac1 100644
--- a/contrib/llvm-project/lldb/include/lldb/Host/PseudoTerminal.h
+++ b/contrib/llvm-project/lldb/include/lldb/Host/PseudoTerminal.h
@@ -9,11 +9,11 @@
#ifndef LLDB_HOST_PSEUDOTERMINAL_H
#define LLDB_HOST_PSEUDOTERMINAL_H
+#include "lldb/lldb-defines.h"
+#include "llvm/Support/Error.h"
#include <fcntl.h>
#include <string>
-#include "lldb/lldb-defines.h"
-
namespace lldb_private {
/// \class PseudoTerminal PseudoTerminal.h "lldb/Host/PseudoTerminal.h"
@@ -62,15 +62,11 @@ public:
/// @li PseudoTerminal::ReleasePrimaryFileDescriptor() @li
/// PseudoTerminal::ReleaseSaveFileDescriptor()
///
- /// \param[out] error_str
- /// An pointer to an error that can describe any errors that
- /// occur. This can be NULL if no error status is desired.
- ///
/// \return
/// \b Parent process: a child process ID that is greater
- /// than zero, or -1 if the fork fails.
+ /// than zero, or an error if the fork fails.
/// \b Child process: zero.
- lldb::pid_t Fork(char *error_str, size_t error_len);
+ llvm::Expected<lldb::pid_t> Fork();
/// The primary file descriptor accessor.
///
@@ -105,20 +101,11 @@ public:
/// A primary pseudo terminal should already be valid prior to
/// calling this function.
///
- /// \param[out] error_str
- /// An pointer to an error that can describe any errors that
- /// occur. This can be NULL if no error status is desired.
- ///
/// \return
- /// The name of the secondary pseudo terminal as a NULL terminated
- /// C. This string that comes from static memory, so a copy of
- /// the string should be made as subsequent calls can change
- /// this value. NULL is returned if this object doesn't have
- /// a valid primary pseudo terminal opened or if the call to
- /// \c ptsname() fails.
+ /// The name of the secondary pseudo terminal.
///
/// \see PseudoTerminal::OpenFirstAvailablePrimary()
- const char *GetSecondaryName(char *error_str, size_t error_len) const;
+ std::string GetSecondaryName() const;
/// Open the first available pseudo terminal.
///
@@ -137,18 +124,9 @@ public:
/// Flags to use when calling \c posix_openpt(\a oflag).
/// A value of "O_RDWR|O_NOCTTY" is suggested.
///
- /// \param[out] error_str
- /// An pointer to an error that can describe any errors that
- /// occur. This can be NULL if no error status is desired.
- ///
- /// \return
- /// \b true when the primary files descriptor is
- /// successfully opened.
- /// \b false if anything goes wrong.
- ///
/// \see PseudoTerminal::GetPrimaryFileDescriptor() @see
/// PseudoTerminal::ReleasePrimaryFileDescriptor()
- bool OpenFirstAvailablePrimary(int oflag, char *error_str, size_t error_len);
+ llvm::Error OpenFirstAvailablePrimary(int oflag);
/// Open the secondary for the current primary pseudo terminal.
///
@@ -166,19 +144,10 @@ public:
/// \param[in] oflag
/// Flags to use when calling \c open(\a oflag).
///
- /// \param[out] error_str
- /// An pointer to an error that can describe any errors that
- /// occur. This can be NULL if no error status is desired.
- ///
- /// \return
- /// \b true when the primary files descriptor is
- /// successfully opened.
- /// \b false if anything goes wrong.
- ///
/// \see PseudoTerminal::OpenFirstAvailablePrimary() @see
/// PseudoTerminal::GetSecondaryFileDescriptor() @see
/// PseudoTerminal::ReleaseSecondaryFileDescriptor()
- bool OpenSecondary(int oflag, char *error_str, size_t error_len);
+ llvm::Error OpenSecondary(int oflag);
/// Release the primary file descriptor.
///
diff --git a/contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h b/contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h
index 2faab6f587cd..5be9cb657382 100644
--- a/contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h
+++ b/contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h
@@ -17,6 +17,7 @@
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/TraceOptions.h"
+#include "lldb/Utility/UnimplementedError.h"
#include "lldb/lldb-private-forward.h"
#include "lldb/lldb-types.h"
#include "llvm/ADT/ArrayRef.h"
@@ -112,10 +113,14 @@ public:
virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
size_t &bytes_written) = 0;
- virtual Status AllocateMemory(size_t size, uint32_t permissions,
- lldb::addr_t &addr) = 0;
+ virtual llvm::Expected<lldb::addr_t> AllocateMemory(size_t size,
+ uint32_t permissions) {
+ return llvm::make_error<UnimplementedError>();
+ }
- virtual Status DeallocateMemory(lldb::addr_t addr) = 0;
+ virtual llvm::Error DeallocateMemory(lldb::addr_t addr) {
+ return llvm::make_error<UnimplementedError>();
+ }
virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0;
@@ -387,6 +392,11 @@ public:
return Status("Not implemented");
}
+ /// \copydoc Process::GetSupportedTraceType()
+ virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType() {
+ return llvm::make_error<UnimplementedError>();
+ }
+
protected:
struct SoftwareBreakpoint {
uint32_t ref_count;
diff --git a/contrib/llvm-project/lldb/include/lldb/Host/common/NativeRegisterContext.h b/contrib/llvm-project/lldb/include/lldb/Host/common/NativeRegisterContext.h
index 3b54d4ae1e05..f7568fe31b80 100644
--- a/contrib/llvm-project/lldb/include/lldb/Host/common/NativeRegisterContext.h
+++ b/contrib/llvm-project/lldb/include/lldb/Host/common/NativeRegisterContext.h
@@ -16,6 +16,8 @@ namespace lldb_private {
class NativeThreadProtocol;
+enum class ExpeditedRegs { Minimal, Full };
+
class NativeRegisterContext
: public std::enable_shared_from_this<NativeRegisterContext> {
public:
@@ -75,6 +77,8 @@ public:
virtual bool ClearHardwareWatchpoint(uint32_t hw_index);
+ virtual Status ClearWatchpointHit(uint32_t hw_index);
+
virtual Status ClearAllHardwareWatchpoints();
virtual Status IsWatchpointHit(uint32_t wp_index, bool &is_hit);
@@ -114,6 +118,11 @@ public:
virtual NativeThreadProtocol &GetThread() { return m_thread; }
+ virtual std::vector<uint32_t>
+ GetExpeditedRegisters(ExpeditedRegs expType) const;
+
+ virtual bool RegisterOffsetIsDynamic() const { return false; }
+
const RegisterInfo *GetRegisterInfoByName(llvm::StringRef reg_name,
uint32_t start_idx = 0);
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandCompletions.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandCompletions.h
index 39d1c98eaa39..c80bde0e719b 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandCompletions.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandCompletions.h
@@ -37,10 +37,23 @@ public:
eRegisterCompletion = (1u << 9),
eBreakpointCompletion = (1u << 10),
eProcessPluginCompletion = (1u << 11),
+ eDisassemblyFlavorCompletion = (1u << 12),
+ eTypeLanguageCompletion = (1u << 13),
+ eFrameIndexCompletion = (1u << 14),
+ eModuleUUIDCompletion = (1u << 15),
+ eStopHookIDCompletion = (1u << 16),
+ eThreadIndexCompletion = (1u << 17),
+ eWatchPointIDCompletion = (1u << 18),
+ eBreakpointNameCompletion = (1u << 19),
+ eProcessIDCompletion = (1u << 20),
+ eProcessNameCompletion = (1u << 21),
+ eRemoteDiskFileCompletion = (1u << 22),
+ eRemoteDiskDirectoryCompletion = (1u << 23),
+ eTypeCategoryNameCompletion = (1u << 24),
// This item serves two purposes. It is the last element in the enum, so
// you can add custom enums starting from here in your Option class. Also
// if you & in this bit the base code will not process the option.
- eCustomCompletion = (1u << 12)
+ eCustomCompletion = (1u << 24)
};
static bool InvokeCommonCompletionCallbacks(
@@ -62,12 +75,23 @@ public:
StringList &matches,
TildeExpressionResolver &Resolver);
+ static void RemoteDiskFiles(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher);
+
+ static void RemoteDiskDirectories(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher);
+
static void SourceFiles(CommandInterpreter &interpreter,
CompletionRequest &request, SearchFilter *searcher);
static void Modules(CommandInterpreter &interpreter,
CompletionRequest &request, SearchFilter *searcher);
+ static void ModuleUUIDs(CommandInterpreter &interpreter,
+ CompletionRequest &request, SearchFilter *searcher);
+
static void Symbols(CommandInterpreter &interpreter,
CompletionRequest &request, SearchFilter *searcher);
@@ -91,9 +115,42 @@ public:
static void Breakpoints(CommandInterpreter &interpreter,
CompletionRequest &request, SearchFilter *searcher);
+ static void BreakpointNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher);
+
static void ProcessPluginNames(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher);
+
+ static void ProcessIDs(CommandInterpreter &interpreter,
+ CompletionRequest &request, SearchFilter *searcher);
+
+ static void ProcessNames(CommandInterpreter &interpreter,
+ CompletionRequest &request, SearchFilter *searcher);
+
+ static void DisassemblyFlavors(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher);
+
+ static void TypeLanguages(CommandInterpreter &interpreter,
+ CompletionRequest &request, SearchFilter *searcher);
+
+ static void FrameIndexes(CommandInterpreter &interpreter,
+ CompletionRequest &request, SearchFilter *searcher);
+
+ static void StopHookIDs(CommandInterpreter &interpreter,
+ CompletionRequest &request, SearchFilter *searcher);
+
+ static void ThreadIndexes(CommandInterpreter &interpreter,
+ CompletionRequest &request, SearchFilter *searcher);
+
+ static void WatchPointIDs(CommandInterpreter &interpreter,
+ CompletionRequest &request, SearchFilter *searcher);
+
+ static void TypeCategoryNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher);
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h
index 8a9dce7a19bc..c4f9dd2fdb37 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h
@@ -20,6 +20,7 @@
#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StringList.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
@@ -255,7 +256,7 @@ public:
}
void SourceInitFileCwd(CommandReturnObject &result);
- void SourceInitFileHome(CommandReturnObject &result);
+ void SourceInitFileHome(CommandReturnObject &result, bool is_repl = false);
bool AddCommand(llvm::StringRef name, const lldb::CommandObjectSP &cmd_sp,
bool can_replace);
@@ -264,7 +265,7 @@ public:
bool can_replace);
lldb::CommandObjectSP GetCommandSPExact(llvm::StringRef cmd,
- bool include_aliases) const;
+ bool include_aliases = false) const;
CommandObject *GetCommandObject(llvm::StringRef cmd,
StringList *matches = nullptr,
@@ -350,6 +351,10 @@ public:
CommandObject *GetCommandObjectForCommand(llvm::StringRef &command_line);
+ /// Returns the auto-suggestion string that should be added to the given
+ /// command line.
+ llvm::Optional<std::string> GetAutoSuggestionForCommand(llvm::StringRef line);
+
// This handles command line completion.
void HandleCompletion(CompletionRequest &request);
@@ -485,9 +490,11 @@ public:
bool GetExpandRegexAliases() const;
bool GetPromptOnQuit() const;
-
void SetPromptOnQuit(bool enable);
+ bool GetSaveSessionOnQuit() const;
+ void SetSaveSessionOnQuit(bool enable);
+
bool GetEchoCommands() const;
void SetEchoCommands(bool enable);
@@ -498,6 +505,12 @@ public:
return m_user_dict;
}
+ const CommandObject::CommandMap &GetCommands() const {
+ return m_command_dict;
+ }
+
+ const CommandObject::CommandMap &GetAliases() const { return m_alias_dict; }
+
/// Specify if the command interpreter should allow that the user can
/// specify a custom exit code when calling 'quit'.
void AllowExitCodeOnQuit(bool allow);
@@ -526,6 +539,20 @@ public:
bool GetSpaceReplPrompts() const;
+ /// Save the current debugger session transcript to a file on disk.
+ /// \param output_file
+ /// The file path to which the session transcript will be written. Since
+ /// the argument is optional, an arbitrary temporary file will be create
+ /// when no argument is passed.
+ /// \param result
+ /// This is used to pass function output and error messages.
+ /// \return \b true if the session transcript was successfully written to
+ /// disk, \b false otherwise.
+ bool SaveTranscript(CommandReturnObject &result,
+ llvm::Optional<std::string> output_file = llvm::None);
+
+ FileSpec GetCurrentSourceDir();
+
protected:
friend class Debugger;
@@ -612,7 +639,13 @@ private:
ChildrenTruncatedWarningStatus m_truncation_warning; // Whether we truncated
// children and whether
// the user has been told
+
+ // FIXME: Stop using this to control adding to the history and then replace
+ // this with m_command_source_dirs.size().
uint32_t m_command_source_depth;
+ /// A stack of directory paths. When not empty, the last one is the directory
+ /// of the file that's currently sourced.
+ std::vector<FileSpec> m_command_source_dirs;
std::vector<uint32_t> m_command_source_flags;
CommandInterpreterRunResult m_result;
@@ -621,6 +654,8 @@ private:
llvm::Optional<int> m_quit_exit_code;
// If the driver is accepts custom exit codes for the 'quit' command.
bool m_allow_exit_code = false;
+
+ StreamString m_transcript_stream;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h
index cc4d40b23c31..d5ad969cda66 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h
@@ -90,14 +90,15 @@ public:
{
lldb::CommandArgumentType arg_type;
ArgumentRepetitionType arg_repetition;
- uint32_t arg_opt_set_association; // This arg might be associated only with
- // some particular option set(s).
- CommandArgumentData()
- : arg_type(lldb::eArgTypeNone), arg_repetition(eArgRepeatPlain),
- arg_opt_set_association(LLDB_OPT_SET_ALL) // By default, the arg
- // associates to all option
- // sets.
- {}
+ /// This arg might be associated only with some particular option set(s). By
+ /// default the arg associates to all option sets.
+ uint32_t arg_opt_set_association;
+
+ CommandArgumentData(lldb::CommandArgumentType type = lldb::eArgTypeNone,
+ ArgumentRepetitionType repetition = eArgRepeatPlain,
+ uint32_t opt_set = LLDB_OPT_SET_ALL)
+ : arg_type(type), arg_repetition(repetition),
+ arg_opt_set_association(opt_set) {}
};
typedef std::vector<CommandArgumentData>
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h
index 6b383f8cfb34..f330a745f9bd 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h
@@ -82,6 +82,10 @@ public:
// for this object.
virtual CommandObject *GetProxyCommandObject() = 0;
+ llvm::StringRef GetSyntax() override;
+
+ llvm::StringRef GetHelp() override;
+
llvm::StringRef GetHelpLong() override;
bool IsRemovable() const override;
@@ -121,6 +125,11 @@ public:
const char *GetRepeatCommand(Args &current_command_args,
uint32_t index) override;
+ /// \return
+ /// An error message to be displayed when the command is executed (i.e.
+ /// Execute is called) and \a GetProxyCommandObject returned null.
+ virtual llvm::StringRef GetUnsupportedError();
+
bool Execute(const char *args_string, CommandReturnObject &result) override;
protected:
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h
index 5b07427094bf..a8176e39940a 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h
@@ -31,6 +31,7 @@ public:
eTypeChar,
eTypeDictionary,
eTypeEnum,
+ eTypeFileLineColumn,
eTypeFileSpec,
eTypeFileSpecList,
eTypeFormat,
@@ -84,7 +85,7 @@ public:
SetValueFromString(llvm::StringRef value,
VarSetOperationType op = eVarSetOperationAssign);
- virtual bool Clear() = 0;
+ virtual void Clear() = 0;
virtual lldb::OptionValueSP DeepCopy() const = 0;
@@ -135,6 +136,8 @@ public:
return eTypeDictionary;
case 1u << eTypeEnum:
return eTypeEnum;
+ case 1u << eTypeFileLineColumn:
+ return eTypeFileLineColumn;
case 1u << eTypeFileSpec:
return eTypeFileSpec;
case 1u << eTypeFileSpecList:
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArch.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArch.h
index 7b63c68fddbf..809261ef22c3 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArch.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArch.h
@@ -47,10 +47,9 @@ public:
SetValueFromString(const char *,
VarSetOperationType = eVarSetOperationAssign) = delete;
- bool Clear() override {
+ void Clear() override {
m_current_value = m_default_value;
m_value_was_set = false;
- return true;
}
lldb::OptionValueSP DeepCopy() const override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArray.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArray.h
index 000351c2f586..4546bbb80394 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArray.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueArray.h
@@ -36,10 +36,9 @@ public:
SetValueFromString(const char *,
VarSetOperationType = eVarSetOperationAssign) = delete;
- bool Clear() override {
+ void Clear() override {
m_values.clear();
m_value_was_set = false;
- return true;
}
lldb::OptionValueSP DeepCopy() const override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueBoolean.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueBoolean.h
index d221f6d034c2..1af14a4980ed 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueBoolean.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueBoolean.h
@@ -37,10 +37,9 @@ public:
SetValueFromString(const char *,
VarSetOperationType = eVarSetOperationAssign) = delete;
- bool Clear() override {
+ void Clear() override {
m_current_value = m_default_value;
m_value_was_set = false;
- return true;
}
void AutoComplete(CommandInterpreter &interpreter,
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueChar.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueChar.h
index 8d0aa91d7076..a8ecf507a4cf 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueChar.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueChar.h
@@ -38,10 +38,9 @@ public:
SetValueFromString(const char *,
VarSetOperationType = eVarSetOperationAssign) = delete;
- bool Clear() override {
+ void Clear() override {
m_current_value = m_default_value;
m_value_was_set = false;
- return true;
}
// Subclass specific functions
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h
index 1bc45252607c..dab1c3ea0c1c 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueDictionary.h
@@ -35,10 +35,9 @@ public:
SetValueFromString(llvm::StringRef value,
VarSetOperationType op = eVarSetOperationAssign) override;
- bool Clear() override {
+ void Clear() override {
m_values.clear();
m_value_was_set = false;
- return true;
}
lldb::OptionValueSP DeepCopy() const override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueEnumeration.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueEnumeration.h
index 26ba7ad5f646..12c6473c7f1c 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueEnumeration.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueEnumeration.h
@@ -47,10 +47,9 @@ public:
SetValueFromString(const char *,
VarSetOperationType = eVarSetOperationAssign) = delete;
- bool Clear() override {
+ void Clear() override {
m_current_value = m_default_value;
m_value_was_set = false;
- return true;
}
lldb::OptionValueSP DeepCopy() const override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h
new file mode 100644
index 000000000000..713deea9e141
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h
@@ -0,0 +1,64 @@
+//===-- OptionValueFileColonLine.h ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_INTERPRETER_OPTIONVALUEFILECOLONLINE_H
+#define LLDB_INTERPRETER_OPTIONVALUEFILECOLONLINE_H
+
+#include "lldb/Interpreter/OptionValue.h"
+
+#include "lldb/Utility/FileSpec.h"
+#include "llvm/Support/Chrono.h"
+
+namespace lldb_private {
+
+class OptionValueFileColonLine : public OptionValue {
+public:
+ OptionValueFileColonLine();
+ OptionValueFileColonLine(const llvm::StringRef input);
+
+ ~OptionValueFileColonLine() override {}
+
+ OptionValue::Type GetType() const override { return eTypeFileLineColumn; }
+
+ void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
+ uint32_t dump_mask) override;
+
+ Status
+ SetValueFromString(llvm::StringRef value,
+ VarSetOperationType op = eVarSetOperationAssign) override;
+ Status
+ SetValueFromString(const char *,
+ VarSetOperationType = eVarSetOperationAssign) = delete;
+
+ void Clear() override {
+ m_file_spec.Clear();
+ m_line_number = LLDB_INVALID_LINE_NUMBER;
+ m_column_number = LLDB_INVALID_COLUMN_NUMBER;
+ }
+
+ lldb::OptionValueSP DeepCopy() const override;
+
+ void AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) override;
+
+ FileSpec &GetFileSpec() { return m_file_spec; }
+ uint32_t GetLineNumber() { return m_line_number; }
+ uint32_t GetColumnNumber() { return m_column_number; }
+
+ void SetCompletionMask(uint32_t mask) { m_completion_mask = mask; }
+
+protected:
+ FileSpec m_file_spec;
+ uint32_t m_line_number;
+ uint32_t m_column_number;
+ uint32_t m_completion_mask;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_INTERPRETER_OPTIONVALUEFILECOLONLINE_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpec.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpec.h
index 2b18c9533f91..4fde3f6e3c8a 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpec.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpec.h
@@ -41,12 +41,11 @@ public:
SetValueFromString(const char *,
VarSetOperationType = eVarSetOperationAssign) = delete;
- bool Clear() override {
+ void Clear() override {
m_current_value = m_default_value;
m_value_was_set = false;
m_data_sp.reset();
m_data_mod_time = llvm::sys::TimePoint<>();
- return true;
}
lldb::OptionValueSP DeepCopy() const override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h
index 7b762bf6b309..38773525c8db 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h
@@ -39,11 +39,10 @@ public:
SetValueFromString(const char *,
VarSetOperationType = eVarSetOperationAssign) = delete;
- bool Clear() override {
+ void Clear() override {
std::lock_guard<std::recursive_mutex> lock(m_mutex);
m_current_value.Clear();
m_value_was_set = false;
- return true;
}
lldb::OptionValueSP DeepCopy() const override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormat.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormat.h
index 6904c93a2f33..5a83ff3b8983 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormat.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormat.h
@@ -38,10 +38,9 @@ public:
SetValueFromString(const char *,
VarSetOperationType = eVarSetOperationAssign) = delete;
- bool Clear() override {
+ void Clear() override {
m_current_value = m_default_value;
m_value_was_set = false;
- return true;
}
lldb::OptionValueSP DeepCopy() const override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h
index beb5d6843a98..7c2f9fba0242 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h
@@ -34,7 +34,7 @@ public:
SetValueFromString(const char *,
VarSetOperationType = eVarSetOperationAssign) = delete;
- bool Clear() override;
+ void Clear() override;
lldb::OptionValueSP DeepCopy() const override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueLanguage.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueLanguage.h
index f4ca2fd69ab5..129365296759 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueLanguage.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueLanguage.h
@@ -41,10 +41,9 @@ public:
SetValueFromString(const char *,
VarSetOperationType = eVarSetOperationAssign) = delete;
- bool Clear() override {
+ void Clear() override {
m_current_value = m_default_value;
m_value_was_set = false;
- return true;
}
lldb::OptionValueSP DeepCopy() const override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValuePathMappings.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValuePathMappings.h
index 18f5cbaf4336..6d1a0816f45b 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValuePathMappings.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValuePathMappings.h
@@ -35,10 +35,9 @@ public:
SetValueFromString(const char *,
VarSetOperationType = eVarSetOperationAssign) = delete;
- bool Clear() override {
+ void Clear() override {
m_path_mappings.Clear(m_notify_changes);
m_value_was_set = false;
- return true;
}
lldb::OptionValueSP DeepCopy() const override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h
index 76f09cc77123..d60afdeb46fb 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueProperties.h
@@ -34,7 +34,7 @@ public:
Type GetType() const override { return eTypeProperties; }
- bool Clear() override;
+ void Clear() override;
lldb::OptionValueSP DeepCopy() const override;
@@ -104,11 +104,6 @@ public:
Status SetSubValue(const ExecutionContext *exe_ctx, VarSetOperationType op,
llvm::StringRef path, llvm::StringRef value) override;
- virtual bool PredicateMatches(const ExecutionContext *exe_ctx,
- llvm::StringRef predicate) const {
- return false;
- }
-
OptionValueArch *
GetPropertyAtIndexAsOptionValueArch(const ExecutionContext *exe_ctx,
uint32_t idx) const;
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueRegex.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueRegex.h
index b09b8414d5bf..4751a1dc27ed 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueRegex.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueRegex.h
@@ -36,10 +36,9 @@ public:
SetValueFromString(const char *,
VarSetOperationType = eVarSetOperationAssign) = delete;
- bool Clear() override {
+ void Clear() override {
m_regex = RegularExpression(m_default_regex_str);
m_value_was_set = false;
- return true;
}
lldb::OptionValueSP DeepCopy() const override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueSInt64.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueSInt64.h
index fbabaaeb2ff4..87917c108865 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueSInt64.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueSInt64.h
@@ -50,10 +50,9 @@ public:
SetValueFromString(const char *,
VarSetOperationType = eVarSetOperationAssign) = delete;
- bool Clear() override {
+ void Clear() override {
m_current_value = m_default_value;
m_value_was_set = false;
- return true;
}
lldb::OptionValueSP DeepCopy() const override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h
index cd371c567020..ed44dae67d1d 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueString.h
@@ -85,10 +85,9 @@ public:
SetValueFromString(const char *,
VarSetOperationType = eVarSetOperationAssign) = delete;
- bool Clear() override {
+ void Clear() override {
m_current_value = m_default_value;
m_value_was_set = false;
- return true;
}
lldb::OptionValueSP DeepCopy() const override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUInt64.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUInt64.h
index 0096e87de367..1164fb802f68 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUInt64.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUInt64.h
@@ -47,10 +47,9 @@ public:
SetValueFromString(const char *,
VarSetOperationType = eVarSetOperationAssign) = delete;
- bool Clear() override {
+ void Clear() override {
m_current_value = m_default_value;
m_value_was_set = false;
- return true;
}
lldb::OptionValueSP DeepCopy() const override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUUID.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUUID.h
index 2fb8caa3aa53..1f663e999b9d 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUUID.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValueUUID.h
@@ -36,10 +36,9 @@ public:
SetValueFromString(const char *,
VarSetOperationType = eVarSetOperationAssign) = delete;
- bool Clear() override {
+ void Clear() override {
m_uuid.Clear();
m_value_was_set = false;
- return true;
}
lldb::OptionValueSP DeepCopy() const override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValues.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValues.h
index 36e7c192d60a..6efc9e1ad064 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValues.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValues.h
@@ -17,6 +17,7 @@
#include "lldb/Interpreter/OptionValueChar.h"
#include "lldb/Interpreter/OptionValueDictionary.h"
#include "lldb/Interpreter/OptionValueEnumeration.h"
+#include "lldb/Interpreter/OptionValueFileColonLine.h"
#include "lldb/Interpreter/OptionValueFileSpec.h"
#include "lldb/Interpreter/OptionValueFileSpecList.h"
#include "lldb/Interpreter/OptionValueFormat.h"
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h
index ebceaea8383d..9738cce2f7a1 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/Options.h
@@ -14,6 +14,7 @@
#include "lldb/Utility/Args.h"
#include "lldb/Utility/CompletionRequest.h"
+#include "lldb/Utility/OptionDefinition.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-private.h"
@@ -40,12 +41,6 @@ struct OptionArgElement {
typedef std::vector<OptionArgElement> OptionElementVector;
-static inline bool isprint8(int ch) {
- if (ch & 0xffffff00u)
- return false;
- return llvm::isPrint(ch);
-}
-
/// \class Options Options.h "lldb/Interpreter/Options.h"
/// A command line option parsing protocol class.
///
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h
index 491923e6a6c4..4abd1ca68167 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -298,6 +298,23 @@ public:
return lldb::eSearchDepthModule;
}
+ virtual StructuredData::GenericSP
+ CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name,
+ StructuredDataImpl *args_data, Status &error) {
+ error.SetErrorString("Creating scripted stop-hooks with the current "
+ "script interpreter is not supported.");
+ return StructuredData::GenericSP();
+ }
+
+ // This dispatches to the handle_stop method of the stop-hook class. It
+ // returns a "should_stop" bool.
+ virtual bool
+ ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp,
+ ExecutionContext &exc_ctx,
+ lldb::StreamSP stream_sp) {
+ return true;
+ }
+
virtual StructuredData::ObjectSP
LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) {
return StructuredData::ObjectSP();
@@ -490,7 +507,8 @@ public:
virtual bool
LoadScriptingModule(const char *filename, bool init_session,
lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp = nullptr);
+ StructuredData::ObjectSP *module_sp = nullptr,
+ FileSpec extra_search_dir = {});
virtual bool IsReservedWord(const char *word) { return false; }
diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/CompilerType.h b/contrib/llvm-project/lldb/include/lldb/Symbol/CompilerType.h
index 280966a327ec..5a0e8e57200d 100644
--- a/contrib/llvm-project/lldb/include/lldb/Symbol/CompilerType.h
+++ b/contrib/llvm-project/lldb/include/lldb/Symbol/CompilerType.h
@@ -20,7 +20,7 @@ namespace lldb_private {
class DataExtractor;
-/// Represents a generic type in a programming language.
+/// Generic representation of a type in a programming language.
///
/// This class serves as an abstraction for a type inside one of the TypeSystems
/// implemented by the language plugins. It does not have any actual logic in it
@@ -82,6 +82,8 @@ public:
bool IsAnonymousType() const;
+ bool IsScopedEnumerationType() const;
+
bool IsBeingDefined() const;
bool IsCharType() const;
@@ -96,7 +98,7 @@ public:
bool IsFloatingPointType(uint32_t &count, bool &is_complex) const;
- bool IsFunctionType(bool *is_variadic_ptr = nullptr) const;
+ bool IsFunctionType() const;
uint32_t IsHomogeneousAggregate(CompilerType *base_type_ptr) const;
@@ -177,7 +179,7 @@ public:
/// Creating related types.
/// \{
- CompilerType GetArrayElementType(uint64_t *stride = nullptr) const;
+ CompilerType GetArrayElementType(ExecutionContextScope *exe_scope) const;
CompilerType GetArrayType(uint64_t size) const;
@@ -185,6 +187,8 @@ public:
CompilerType GetFullyUnqualifiedType() const;
+ CompilerType GetEnumerationIntegerType() const;
+
/// Returns -1 if this isn't a function of if the function doesn't
/// have a prototype Returns a value >= 0 if there is a prototype.
int GetFunctionArgumentCount() const;
@@ -383,7 +387,8 @@ public:
/// \}
bool GetValueAsScalar(const DataExtractor &data, lldb::offset_t data_offset,
- size_t data_byte_size, Scalar &value) const;
+ size_t data_byte_size, Scalar &value,
+ ExecutionContextScope *exe_scope) const;
void Clear() {
m_type = nullptr;
m_type_system = nullptr;
diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h b/contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h
index d66b58ca4c6d..b48e82f19ffb 100644
--- a/contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h
+++ b/contrib/llvm-project/lldb/include/lldb/Symbol/LineTable.h
@@ -9,6 +9,7 @@
#ifndef LLDB_SYMBOL_LINETABLE_H
#define LLDB_SYMBOL_LINETABLE_H
+#include "lldb/Core/Address.h"
#include "lldb/Core/ModuleChild.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/LineEntry.h"
diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h b/contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h
index e814015c0bf7..080724cb86bd 100644
--- a/contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h
+++ b/contrib/llvm-project/lldb/include/lldb/Symbol/ObjectFile.h
@@ -91,6 +91,17 @@ public:
eStrataJIT
};
+ /// If we have a corefile binary hint, this enum
+ /// specifies the binary type which we can use to
+ /// select the correct DynamicLoader plugin.
+ enum BinaryType {
+ eBinaryTypeInvalid = 0,
+ eBinaryTypeUnknown,
+ eBinaryTypeKernel, /// kernel binary
+ eBinaryTypeUser, /// user process binary
+ eBinaryTypeStandalone /// standalone binary / firmware
+ };
+
struct LoadableData {
lldb::addr_t Dest;
llvm::ArrayRef<uint8_t> Contents;
@@ -500,12 +511,17 @@ public:
/// If the uuid of the binary is specified, this will be set.
/// If no UUID is available, will be cleared.
///
+ /// \param[out] type
+ /// Return the type of the binary, which will dictate which
+ /// DynamicLoader plugin should be used.
+ ///
/// \return
/// Returns true if either address or uuid has been set.
- virtual bool GetCorefileMainBinaryInfo (lldb::addr_t &address, UUID &uuid) {
- address = LLDB_INVALID_ADDRESS;
- uuid.Clear();
- return false;
+ virtual bool GetCorefileMainBinaryInfo(lldb::addr_t &address, UUID &uuid,
+ ObjectFile::BinaryType &type) {
+ address = LLDB_INVALID_ADDRESS;
+ uuid.Clear();
+ return false;
}
virtual lldb::RegisterContextSP
diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolContext.h b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolContext.h
index cc49ce51c713..c513dbb447f8 100644
--- a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolContext.h
+++ b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolContext.h
@@ -139,11 +139,19 @@ public:
/// be printed. In disassembly formatting, where we want a format
/// like "<*+36>", this should be false and "*" will be printed
/// instead.
+ ///
+ /// \param[in] show_inline_callsite_line_info
+ /// When processing an inline block, the line info of the callsite
+ /// is dumped if this flag is \b true, otherwise the line info
+ /// of the actual inlined function is dumped.
+ ///
+ /// \return
+ /// \b true if some text was dumped, \b false otherwise.
bool DumpStopContext(Stream *s, ExecutionContextScope *exe_scope,
const Address &so_addr, bool show_fullpaths,
bool show_module, bool show_inlined_frames,
- bool show_function_arguments,
- bool show_function_name) const;
+ bool show_function_arguments, bool show_function_name,
+ bool show_inline_callsite_line_info = true) const;
/// Get the address range contained within a symbol context.
///
@@ -340,7 +348,7 @@ public:
void Clear();
- bool SymbolContextMatches(SymbolContext &sc);
+ bool SymbolContextMatches(const SymbolContext &sc);
bool AddressMatches(lldb::addr_t addr);
diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolVendor.h b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolVendor.h
index c9c59a3fc1be..5c785e8c5a85 100644
--- a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolVendor.h
+++ b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolVendor.h
@@ -14,6 +14,7 @@
#include "lldb/Core/ModuleChild.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Symbol/SourceModule.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/lldb-private.h"
#include "llvm/ADT/DenseSet.h"
@@ -35,8 +36,6 @@ public:
// Constructors and Destructors
SymbolVendor(const lldb::ModuleSP &module_sp);
- ~SymbolVendor() override;
-
void AddSymbolFileRepresentation(const lldb::ObjectFileSP &objfile_sp);
SymbolFile *GetSymbolFile() { return m_sym_file_up.get(); }
@@ -49,11 +48,6 @@ public:
protected:
std::unique_ptr<SymbolFile> m_sym_file_up; // A single symbol file. Subclasses
// can add more of these if needed.
-
-private:
- // For SymbolVendor only
- SymbolVendor(const SymbolVendor &) = delete;
- const SymbolVendor &operator=(const SymbolVendor &) = delete;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/Type.h b/contrib/llvm-project/lldb/include/lldb/Symbol/Type.h
index 8735d016bb22..dd917cfb7ca8 100644
--- a/contrib/llvm-project/lldb/include/lldb/Symbol/Type.h
+++ b/contrib/llvm-project/lldb/include/lldb/Symbol/Type.h
@@ -56,6 +56,7 @@ public:
Type *operator->() { return GetType(); }
Type *GetType();
+ SymbolFile &GetSymbolFile() const { return m_symbol_file; }
protected:
SymbolFile &m_symbol_file;
@@ -108,20 +109,27 @@ public:
void DumpTypeName(Stream *s);
- // Since Type instances only keep a "SymbolFile *" internally, other classes
- // like TypeImpl need make sure the module is still around before playing
- // with
- // Type instances. They can store a weak pointer to the Module;
+ /// Since Type instances only keep a "SymbolFile *" internally, other classes
+ /// like TypeImpl need make sure the module is still around before playing
+ /// with
+ /// Type instances. They can store a weak pointer to the Module;
lldb::ModuleSP GetModule();
- void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_name);
+ /// GetModule may return module for compile unit's object file.
+ /// GetExeModule returns module for executable object file that contains
+ /// compile unit where type was actualy defined.
+ /// GetModule and GetExeModule may return the same value.
+ lldb::ModuleSP GetExeModule();
+
+ void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_name,
+ ExecutionContextScope *exe_scope);
SymbolFile *GetSymbolFile() { return m_symbol_file; }
const SymbolFile *GetSymbolFile() const { return m_symbol_file; }
ConstString GetName();
- llvm::Optional<uint64_t> GetByteSize();
+ llvm::Optional<uint64_t> GetByteSize(ExecutionContextScope *exe_scope);
uint32_t GetNumChildren(bool omit_empty_base_classes);
@@ -259,6 +267,8 @@ public:
void Clear();
+ lldb::ModuleSP GetModule() const;
+
ConstString GetName() const;
ConstString GetDisplayTypeName() const;
@@ -286,8 +296,12 @@ public:
private:
bool CheckModule(lldb::ModuleSP &module_sp) const;
+ bool CheckExeModule(lldb::ModuleSP &module_sp) const;
+ bool CheckModuleCommon(const lldb::ModuleWP &input_module_wp,
+ lldb::ModuleSP &module_sp) const;
lldb::ModuleWP m_module_wp;
+ lldb::ModuleWP m_exe_module_wp;
CompilerType m_static_type;
CompilerType m_dynamic_type;
};
diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h b/contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h
index e188f29354b8..1fad8f61ac37 100644
--- a/contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h
+++ b/contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h
@@ -152,8 +152,7 @@ public:
virtual bool IsFloatingPointType(lldb::opaque_compiler_type_t type,
uint32_t &count, bool &is_complex) = 0;
- virtual bool IsFunctionType(lldb::opaque_compiler_type_t type,
- bool *is_variadic_ptr) = 0;
+ virtual bool IsFunctionType(lldb::opaque_compiler_type_t type) = 0;
virtual size_t
GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) = 0;
@@ -176,6 +175,8 @@ public:
return false;
}
+ virtual bool IsScopedEnumerationType(lldb::opaque_compiler_type_t type) = 0;
+
virtual bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
CompilerType *target_type, // Can pass NULL
bool check_cplusplus, bool check_objc) = 0;
@@ -217,14 +218,18 @@ public:
// Creating related types
- virtual CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type,
- uint64_t *stride) = 0;
+ virtual CompilerType
+ GetArrayElementType(lldb::opaque_compiler_type_t type,
+ ExecutionContextScope *exe_scope) = 0;
virtual CompilerType GetArrayType(lldb::opaque_compiler_type_t type,
uint64_t size);
virtual CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) = 0;
+ virtual CompilerType
+ GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) = 0;
+
// Returns -1 if this isn't a function of if the function doesn't have a
// prototype Returns a value >= 0 if there is a prototype.
virtual int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) = 0;
@@ -464,10 +469,8 @@ public:
return nullptr;
}
- virtual UtilityFunction *GetUtilityFunction(const char *text,
- const char *name) {
- return nullptr;
- }
+ virtual std::unique_ptr<UtilityFunction>
+ CreateUtilityFunction(std::string text, std::string name);
virtual PersistentExpressionState *GetPersistentExpressionState() {
return nullptr;
@@ -522,6 +525,22 @@ protected:
///multi-threaded environments.
collection m_map;
bool m_clear_in_progress;
+
+private:
+ typedef llvm::function_ref<lldb::TypeSystemSP()> CreateCallback;
+ /// Finds the type system for the given language. If no type system could be
+ /// found for a language and a CreateCallback was provided, the value returned
+ /// by the callback will be treated as the TypeSystem for the language.
+ ///
+ /// \param language The language for which the type system should be found.
+ /// \param create_callback A callback that will be called if no previously
+ /// created TypeSystem that fits the given language
+ /// could found. Can be omitted if a non-existent
+ /// type system should be treated as an error instead.
+ /// \return The found type system or an error.
+ llvm::Expected<TypeSystem &> GetTypeSystemForLanguage(
+ lldb::LanguageType language,
+ llvm::Optional<CreateCallback> create_callback = llvm::None);
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/UnwindPlan.h b/contrib/llvm-project/lldb/include/lldb/Symbol/UnwindPlan.h
index 8902b5f4eaa7..40814da3de4a 100644
--- a/contrib/llvm-project/lldb/include/lldb/Symbol/UnwindPlan.h
+++ b/contrib/llvm-project/lldb/include/lldb/Symbol/UnwindPlan.h
@@ -393,6 +393,7 @@ public:
m_plan_is_sourced_from_compiler(rhs.m_plan_is_sourced_from_compiler),
m_plan_is_valid_at_all_instruction_locations(
rhs.m_plan_is_valid_at_all_instruction_locations),
+ m_plan_is_for_signal_trap(rhs.m_plan_is_for_signal_trap),
m_lsda_address(rhs.m_lsda_address),
m_personality_func_addr(rhs.m_personality_func_addr) {
m_row_list.reserve(rhs.m_row_list.size());
diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h b/contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h
index 66abdc0b3117..0dcbbd8e4c8e 100644
--- a/contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h
+++ b/contrib/llvm-project/lldb/include/lldb/Symbol/Variable.h
@@ -33,7 +33,8 @@ public:
const lldb::SymbolFileTypeSP &symfile_type_sp, lldb::ValueType scope,
SymbolContextScope *owner_scope, const RangeList &scope_range,
Declaration *decl, const DWARFExpression &location, bool external,
- bool artificial, bool static_member = false);
+ bool artificial, bool location_is_constant_data,
+ bool static_member = false);
virtual ~Variable();
@@ -64,6 +65,8 @@ public:
lldb::ValueType GetScope() const { return m_scope; }
+ const RangeList &GetScopeRange() const { return m_scope_range; }
+
bool IsExternal() const { return m_external; }
bool IsArtificial() const { return m_artificial; }
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ABI.h b/contrib/llvm-project/lldb/include/lldb/Target/ABI.h
index b252e4b54f03..131b2eaff765 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/ABI.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/ABI.h
@@ -159,7 +159,7 @@ public:
protected:
using ABI::ABI;
- bool GetRegisterInfoByName(ConstString name, RegisterInfo &info);
+ bool GetRegisterInfoByName(llvm::StringRef name, RegisterInfo &info);
virtual const RegisterInfo *GetRegisterInfoArray(uint32_t &count) = 0;
};
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h b/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h
index d3ce1b05ed51..dead3eec7013 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h
@@ -68,12 +68,6 @@ public:
/// Construct with a process.
DynamicLoader(Process *process);
- /// Destructor.
- ///
- /// The destructor is virtual since this class is designed to be inherited
- /// from by the plug-in instance.
- ~DynamicLoader() override;
-
/// Called after attaching a process.
///
/// Allow DynamicLoader plug-ins to execute some code after attaching to a
@@ -308,10 +302,6 @@ protected:
// Member variables.
Process
*m_process; ///< The process that this dynamic loader plug-in is tracking.
-
-private:
- DynamicLoader(const DynamicLoader &) = delete;
- const DynamicLoader &operator=(const DynamicLoader &) = delete;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/InstrumentationRuntime.h b/contrib/llvm-project/lldb/include/lldb/Target/InstrumentationRuntime.h
index dd4da26c215e..eeec91f36af4 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/InstrumentationRuntime.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/InstrumentationRuntime.h
@@ -53,7 +53,7 @@ protected:
lldb::ModuleSP GetRuntimeModuleSP() { return m_runtime_module; }
void SetRuntimeModuleSP(lldb::ModuleSP module_sp) {
- m_runtime_module = module_sp;
+ m_runtime_module = std::move(module_sp);
}
lldb::user_id_t GetBreakpointID() const { return m_breakpoint_id; }
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Language.h b/contrib/llvm-project/lldb/include/lldb/Target/Language.h
index 9dc9df363d79..6368828e36da 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/Language.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/Language.h
@@ -211,6 +211,10 @@ public:
// nil/null object, this method returns true
virtual bool IsNilReference(ValueObject &valobj);
+ /// Returns the summary string for ValueObjects for which IsNilReference() is
+ /// true.
+ virtual llvm::StringRef GetNilReferenceSummaryString() { return {}; }
+
// for a ValueObject of some "reference type", if the language provides a
// technique to decide whether the reference has ever been assigned to some
// object, this method will return true if such detection is possible, and if
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h b/contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h
index b0b9b919911a..a3897adfe46a 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/LanguageRuntime.h
@@ -18,6 +18,7 @@
#include "lldb/Expression/LLVMUserExpression.h"
#include "lldb/Symbol/DeclVendor.h"
#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/Runtime.h"
#include "lldb/lldb-private.h"
#include "lldb/lldb-public.h"
@@ -56,10 +57,8 @@ protected:
void UpdateModuleListIfNeeded();
};
-class LanguageRuntime : public PluginInterface {
+class LanguageRuntime : public Runtime, public PluginInterface {
public:
- ~LanguageRuntime() override;
-
static LanguageRuntime *FindPlugin(Process *process,
lldb::LanguageType language);
@@ -127,10 +126,6 @@ public:
return lldb::ThreadSP();
}
- Process *GetProcess() { return m_process; }
-
- Target &GetTargetRef() { return m_process->GetTarget(); }
-
virtual DeclVendor *GetDeclVendor() { return nullptr; }
virtual lldb::BreakpointResolverSP
@@ -159,7 +154,7 @@ public:
return llvm::None;
}
- virtual void ModulesDidLoad(const ModuleList &module_list) {}
+ virtual void ModulesDidLoad(const ModuleList &module_list) override {}
// Called by ClangExpressionParser::PrepareForExecution to query for any
// custom LLVM IR passes that need to be run before an expression is
@@ -179,14 +174,7 @@ public:
static char ID;
protected:
- // Classes that inherit from LanguageRuntime can see and modify these
-
LanguageRuntime(Process *process);
- Process *m_process;
-
-private:
- LanguageRuntime(const LanguageRuntime &) = delete;
- const LanguageRuntime &operator=(const LanguageRuntime &) = delete;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h b/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h
index 9f089b4b0083..392e1edd273e 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h
@@ -24,16 +24,17 @@ public:
MemoryRegionInfo() = default;
MemoryRegionInfo(RangeType range, OptionalBool read, OptionalBool write,
OptionalBool execute, OptionalBool mapped, ConstString name,
- OptionalBool flash, lldb::offset_t blocksize)
+ OptionalBool flash, lldb::offset_t blocksize,
+ OptionalBool memory_tagged)
: m_range(range), m_read(read), m_write(write), m_execute(execute),
- m_mapped(mapped), m_name(name), m_flash(flash), m_blocksize(blocksize) {
- }
+ m_mapped(mapped), m_name(name), m_flash(flash), m_blocksize(blocksize),
+ m_memory_tagged(memory_tagged) {}
RangeType &GetRange() { return m_range; }
void Clear() {
m_range.Clear();
- m_read = m_write = m_execute = eDontKnow;
+ m_read = m_write = m_execute = m_memory_tagged = eDontKnow;
}
const RangeType &GetRange() const { return m_range; }
@@ -48,6 +49,8 @@ public:
ConstString GetName() const { return m_name; }
+ OptionalBool GetMemoryTagged() const { return m_memory_tagged; }
+
void SetReadable(OptionalBool val) { m_read = val; }
void SetWritable(OptionalBool val) { m_write = val; }
@@ -66,6 +69,8 @@ public:
void SetBlocksize(lldb::offset_t blocksize) { m_blocksize = blocksize; }
+ void SetMemoryTagged(OptionalBool val) { m_memory_tagged = val; }
+
// Get permissions as a uint32_t that is a mask of one or more bits from the
// lldb::Permissions
uint32_t GetLLDBPermissions() const {
@@ -91,7 +96,8 @@ public:
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 && m_name == rhs.m_name &&
- m_flash == rhs.m_flash && m_blocksize == rhs.m_blocksize;
+ m_flash == rhs.m_flash && m_blocksize == rhs.m_blocksize &&
+ m_memory_tagged == rhs.m_memory_tagged;
}
bool operator!=(const MemoryRegionInfo &rhs) const { return !(*this == rhs); }
@@ -105,6 +111,7 @@ protected:
ConstString m_name;
OptionalBool m_flash = eDontKnow;
lldb::offset_t m_blocksize = 0;
+ OptionalBool m_memory_tagged = eDontKnow;
};
inline bool operator<(const MemoryRegionInfo &lhs,
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/OperatingSystem.h b/contrib/llvm-project/lldb/include/lldb/Target/OperatingSystem.h
index 6db5c0a01f36..ceeddceb0f2c 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/OperatingSystem.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/OperatingSystem.h
@@ -40,11 +40,8 @@ public:
/// should be used. If NULL, pick the best plug-in.
static OperatingSystem *FindPlugin(Process *process, const char *plugin_name);
- // Class Methods
OperatingSystem(Process *process);
- ~OperatingSystem() override;
-
// Plug-in Methods
virtual bool UpdateThreadList(ThreadList &old_thread_list,
ThreadList &real_thread_list,
@@ -68,9 +65,6 @@ protected:
// Member variables.
Process
*m_process; ///< The process that this dynamic loader plug-in is tracking.
-private:
- OperatingSystem(const OperatingSystem &) = delete;
- const OperatingSystem &operator=(const OperatingSystem &) = delete;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Platform.h b/contrib/llvm-project/lldb/include/lldb/Target/Platform.h
index 277fcf68cb0c..df46466655c3 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/Platform.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/Platform.h
@@ -522,6 +522,9 @@ public:
return UINT64_MAX;
}
+ virtual void AutoCompleteDiskFileOrDirectory(CompletionRequest &request,
+ bool only_dir) {}
+
virtual uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst,
uint64_t dst_len, Status &error) {
error.SetErrorStringWithFormat(
@@ -617,7 +620,18 @@ public:
}
virtual lldb_private::Status RunShellCommand(
- const char *command, // Shouldn't be nullptr
+ llvm::StringRef command,
+ const FileSpec &working_dir, // Pass empty FileSpec to use the current
+ // working directory
+ 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
+ const Timeout<std::micro> &timeout);
+
+ virtual lldb_private::Status RunShellCommand(
+ llvm::StringRef shell, llvm::StringRef command,
const FileSpec &working_dir, // Pass empty FileSpec to use the current
// working directory
int *status_ptr, // Pass nullptr if you don't want the process exit status
@@ -636,7 +650,7 @@ public:
virtual bool CalculateMD5(const FileSpec &file_spec, uint64_t &low,
uint64_t &high);
- virtual int32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) {
+ virtual uint32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) {
return 1;
}
@@ -936,9 +950,6 @@ private:
Platform &remote_platform);
FileSpec GetModuleCacheRoot();
-
- Platform(const Platform &) = delete;
- const Platform &operator=(const Platform &) = delete;
};
class PlatformList {
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/PostMortemProcess.h b/contrib/llvm-project/lldb/include/lldb/Target/PostMortemProcess.h
new file mode 100644
index 000000000000..353bfc0919ee
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Target/PostMortemProcess.h
@@ -0,0 +1,32 @@
+//===-- PostMortemProcess.h -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_POSTMORTEMPROCESS_H
+#define LLDB_TARGET_POSTMORTEMPROCESS_H
+
+#include "lldb/Target/Process.h"
+
+namespace lldb_private {
+
+/// \class PostMortemProcess
+/// Base class for all processes that don't represent a live process, such as
+/// coredumps or processes traced in the past.
+///
+/// \a lldb_private::Process virtual functions overrides that are common
+/// between these kinds of processes can have default implementations in this
+/// class.
+class PostMortemProcess : public Process {
+public:
+ using Process::Process;
+
+ bool IsLiveDebugSession() const override { return false; }
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_TARGET_POSTMORTEMPROCESS_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Process.h b/contrib/llvm-project/lldb/include/lldb/Target/Process.h
index bf9b64547ed5..fbdb5069b39f 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/Process.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/Process.h
@@ -30,7 +30,6 @@
#include "lldb/Host/HostThread.h"
#include "lldb/Host/ProcessLaunchInfo.h"
#include "lldb/Host/ProcessRunLock.h"
-#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/InstrumentationRuntime.h"
@@ -38,6 +37,7 @@
#include "lldb/Target/QueueList.h"
#include "lldb/Target/ThreadList.h"
#include "lldb/Target/ThreadPlanStack.h"
+#include "lldb/Target/Trace.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Broadcaster.h"
#include "lldb/Utility/Event.h"
@@ -47,6 +47,7 @@
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/TraceOptions.h"
+#include "lldb/Utility/UnimplementedError.h"
#include "lldb/Utility/UserIDResolver.h"
#include "lldb/lldb-private.h"
@@ -91,6 +92,7 @@ public:
std::chrono::seconds GetUtilityExpressionTimeout() const;
bool GetOSPluginReportsAllThreads() const;
void SetOSPluginReportsAllThreads(bool does_report);
+ bool GetSteppingRunsAllThreads() const;
protected:
Process *m_process; // Can be nullptr for global ProcessProperties
@@ -207,32 +209,6 @@ protected:
// call SBProcess::Stop() to cancel attach)
};
-class ProcessLaunchCommandOptions : public Options {
-public:
- ProcessLaunchCommandOptions() : Options() {
- // Keep default values of all options in one place: OptionParsingStarting
- // ()
- OptionParsingStarting(nullptr);
- }
-
- ~ProcessLaunchCommandOptions() override = default;
-
- Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
- ExecutionContext *execution_context) override;
-
- void OptionParsingStarting(ExecutionContext *execution_context) override {
- launch_info.Clear();
- disable_aslr = eLazyBoolCalculate;
- }
-
- llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
-
- // Instance variables to hold the values for command options.
-
- ProcessLaunchInfo launch_info;
- lldb_private::LazyBool disable_aslr;
-};
-
// This class tracks the Modification state of the process. Things that can
// currently modify the program are running the program (which will up the
// StopID) and writing memory (which will up the MemoryID.)
@@ -326,7 +302,7 @@ public:
}
void SetStopEventForLastNaturalStopID(lldb::EventSP event_sp) {
- m_last_natural_stop_event = event_sp;
+ m_last_natural_stop_event = std::move(event_sp);
}
lldb::EventSP GetStopEventForStopID(uint32_t stop_id) const {
@@ -361,7 +337,6 @@ inline bool operator!=(const ProcessModID &lhs, const ProcessModID &rhs) {
/// A plug-in interface definition class for debugging a process.
class Process : public std::enable_shared_from_this<Process>,
public ProcessProperties,
- public UserID,
public Broadcaster,
public ExecutionContextScope,
public PluginInterface {
@@ -535,7 +510,8 @@ public:
static lldb::ProcessSP FindPlugin(lldb::TargetSP target_sp,
llvm::StringRef plugin_name,
lldb::ListenerSP listener_sp,
- const FileSpec *crash_file_path);
+ const FileSpec *crash_file_path,
+ bool can_connect);
/// Static function that can be used with the \b host function
/// Host::StartMonitoringChildProcess ().
@@ -557,6 +533,15 @@ public:
uint32_t GetAddressByteSize() const;
+ /// Sets the stored pid.
+ ///
+ /// This does not change the pid of underlying process.
+ lldb::pid_t GetID() const { return m_pid; }
+
+ /// Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is
+ /// no known pid.
+ void SetID(lldb::pid_t new_pid) { m_pid = new_pid; }
+
uint32_t GetUniqueID() const { return m_process_unique_id; }
/// Check if a plug-in instance can debug the file in \a module.
@@ -582,7 +567,7 @@ public:
/// \return
/// Returns \b true if this Process has not been finalized
/// and \b false otherwise.
- bool IsValid() const { return !m_finalize_called; }
+ bool IsValid() const { return !m_finalizing; }
/// Return a multi-word command object that can be used to expose plug-in
/// specific commands.
@@ -727,11 +712,6 @@ public:
/// Attach to a remote system via a URL
///
- /// \param[in] strm
- /// A stream where output intended for the user
- /// (if the driver has a way to display that) generated during
- /// the connection. This may be nullptr if no output is needed.A
- ///
/// \param[in] remote_url
/// The URL format that we are connecting to.
///
@@ -743,6 +723,12 @@ public:
void SetShouldDetach(bool b) { m_should_detach = b; }
+ /// Get the image vector for the current process.
+ ///
+ /// \return
+ /// The constant reference to the member m_image_tokens.
+ const std::vector<lldb::addr_t>& GetImageTokens() { return m_image_tokens; }
+
/// Get the image information address for the current process.
///
/// Some runtimes have system functions that can help dynamic loaders locate
@@ -915,11 +901,6 @@ public:
/// Attach to a remote system via a URL
///
- /// \param[in] strm
- /// A stream where output intended for the user
- /// (if the driver has a way to display that) generated during
- /// the connection. This may be nullptr if no output is needed.A
- ///
/// \param[in] remote_url
/// The URL format that we are connecting to.
///
@@ -1393,6 +1374,8 @@ public:
/// otherwise.
virtual bool IsAlive();
+ virtual bool IsLiveDebugSession() const { return true; };
+
/// Before lldb detaches from a process, it warns the user that they are
/// about to lose their debug session. In some cases, this warning doesn't
/// need to be emitted -- for instance, with core file debugging where the
@@ -1404,35 +1387,6 @@ public:
/// this process.
virtual bool WarnBeforeDetach() const { return true; }
- /// Actually do the reading of memory from a process.
- ///
- /// Subclasses must override this function and can return fewer bytes than
- /// requested when memory requests are too large. This class will break up
- /// the memory requests and keep advancing the arguments along as needed.
- ///
- /// \param[in] vm_addr
- /// A virtual load address that indicates where to start reading
- /// memory from.
- ///
- /// \param[in] size
- /// The number of bytes to read.
- ///
- /// \param[out] buf
- /// A byte buffer that is at least \a size bytes long that
- /// will receive the memory bytes.
- ///
- /// \param[out] error
- /// An error that indicates the success or failure of this
- /// operation. If error indicates success (error.Success()),
- /// then the value returned can be trusted, otherwise zero
- /// will be returned.
- ///
- /// \return
- /// The number of bytes that were actually read into \a buf.
- /// Zero is returned in the case of an error.
- virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
- Status &error) = 0;
-
/// Read of memory from a process.
///
/// This function will read memory from the current process's address space
@@ -2060,8 +2014,17 @@ public:
virtual Status DisableWatchpoint(Watchpoint *wp, bool notify = true);
// Thread Queries
- virtual bool UpdateThreadList(ThreadList &old_thread_list,
- ThreadList &new_thread_list) = 0;
+
+ /// Update the thread list.
+ ///
+ /// This method performs some general clean up before invoking
+ /// \a DoUpdateThreadList, which should be implemented by each
+ /// process plugin.
+ ///
+ /// \return
+ /// \b true if the new thread list could be generated, \b false otherwise.
+ bool UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list);
void UpdateThreadListIfNeeded();
@@ -2163,7 +2126,7 @@ public:
public:
ProcessEventHijacker(Process &process, lldb::ListenerSP listener_sp)
: m_process(process) {
- m_process.HijackProcessEvents(listener_sp);
+ m_process.HijackProcessEvents(std::move(listener_sp));
}
~ProcessEventHijacker() { m_process.RestoreProcessEvents(); }
@@ -2238,7 +2201,7 @@ void PruneThreadPlans();
/// Dump the thread plans associated with thread with \a tid.
///
- /// \param[in/out] strm
+ /// \param[in,out] strm
/// The stream to which to dump the output
///
/// \param[in] tid
@@ -2265,7 +2228,7 @@ void PruneThreadPlans();
/// Dump all the thread plans for this process.
///
- /// \param[in/out] strm
+ /// \param[in,out] strm
/// The stream to which to dump the output
///
/// \param[in] desc_level
@@ -2545,12 +2508,59 @@ void PruneThreadPlans();
return Status("Not implemented");
}
+ /// Get the processor tracing type supported for this process.
+ /// Responses might be different depending on the architecture and
+ /// capabilities of the underlying OS.
+ ///
+ /// \return
+ /// The supported trace type or an \a llvm::Error if tracing is
+ /// not supported for the inferior.
+ virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType();
+
// This calls a function of the form "void * (*)(void)".
bool CallVoidArgVoidPtrReturn(const Address *address,
lldb::addr_t &returned_func,
bool trap_exceptions = false);
protected:
+ /// Update the thread list following process plug-in's specific logic.
+ ///
+ /// This method should only be invoked by \a UpdateThreadList.
+ ///
+ /// \return
+ /// \b true if the new thread list could be generated, \b false otherwise.
+ virtual bool DoUpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) = 0;
+
+ /// Actually do the reading of memory from a process.
+ ///
+ /// Subclasses must override this function and can return fewer bytes than
+ /// requested when memory requests are too large. This class will break up
+ /// the memory requests and keep advancing the arguments along as needed.
+ ///
+ /// \param[in] vm_addr
+ /// A virtual load address that indicates where to start reading
+ /// memory from.
+ ///
+ /// \param[in] size
+ /// The number of bytes to read.
+ ///
+ /// \param[out] buf
+ /// A byte buffer that is at least \a size bytes long that
+ /// will receive the memory bytes.
+ ///
+ /// \param[out] error
+ /// An error that indicates the success or failure of this
+ /// operation. If error indicates success (error.Success()),
+ /// then the value returned can be trusted, otherwise zero
+ /// will be returned.
+ ///
+ /// \return
+ /// The number of bytes that were actually read into \a buf.
+ /// Zero is returned in the case of an error.
+ virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ Status &error) = 0;
+
void SetState(lldb::EventSP &event_sp);
lldb::StateType GetPrivateState();
@@ -2720,6 +2730,7 @@ protected:
// Member variables
std::weak_ptr<Target> m_target_wp; ///< The target that owns this process.
+ lldb::pid_t m_pid = LLDB_INVALID_PROCESS_ID;
ThreadSafeValue<lldb::StateType> m_public_state;
ThreadSafeValue<lldb::StateType>
m_private_state; // The actual state of our process
@@ -2811,10 +2822,11 @@ protected:
// m_currently_handling_do_on_removals are true,
// Resume will only request a resume, using this
// flag to check.
- bool m_finalizing; // This is set at the beginning of Process::Finalize() to
- // stop functions from looking up or creating things
- // during a finalize call
- bool m_finalize_called; // This is set at the end of Process::Finalize()
+
+ /// This is set at the beginning of Process::Finalize() to stop functions
+ /// from looking up or creating things during or after a finalize call.
+ std::atomic<bool> m_finalizing;
+
bool m_clear_thread_plans_on_stop;
bool m_force_next_event_delivery;
lldb::StateType m_last_broadcast_state; /// This helps with the Public event
@@ -2918,6 +2930,8 @@ protected:
void LoadOperatingSystemPlugin(bool flush);
private:
+ Status DestroyImpl(bool force_kill);
+
/// This is the part of the event handling that for a process event. It
/// decides what to do with the event and returns true if the event needs to
/// be propagated to the user, and false otherwise. If the event is not
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ProcessTrace.h b/contrib/llvm-project/lldb/include/lldb/Target/ProcessTrace.h
new file mode 100644
index 000000000000..55faba1576d0
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Target/ProcessTrace.h
@@ -0,0 +1,86 @@
+//===-- ProcessTrace.h ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_PROCESSTRACE_H
+#define LLDB_TARGET_PROCESSTRACE_H
+
+#include "lldb/Target/PostMortemProcess.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Status.h"
+
+namespace lldb_private {
+
+class ProcessTrace : public PostMortemProcess {
+public:
+ static void Initialize();
+
+ static void Terminate();
+
+ static ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ ProcessTrace(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
+
+ ~ProcessTrace() override;
+
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
+
+ void DidAttach(ArchSpec &process_arch) override;
+
+ DynamicLoader *GetDynamicLoader() override { return nullptr; }
+
+ SystemRuntime *GetSystemRuntime() override { return nullptr; }
+
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ Status DoDestroy() override;
+
+ void RefreshStateAfterStop() override;
+
+ Status WillResume() override {
+ Status error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support resuming processes",
+ GetPluginName().GetCString());
+ return error;
+ }
+
+ bool IsAlive() override;
+
+ bool WarnBeforeDetach() const override { return false; }
+
+ size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Status &error) override;
+
+ size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ Status &error) override;
+
+ ArchSpec GetArchitecture();
+
+ bool GetProcessInfo(ProcessInstanceInfo &info) override;
+
+protected:
+ void Clear();
+
+ bool DoUpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) override;
+
+private:
+ static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *crash_file_path,
+ bool can_connect);
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_TARGET_PROCESSTRACE_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h b/contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h
index 5741dbe027b7..6d6ac99c093f 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h
@@ -68,11 +68,16 @@ public:
bool GetRemoteOSKernelDescription(std::string &s) override;
ArchSpec GetRemoteSystemArchitecture() override;
- Status RunShellCommand(const char *command, const FileSpec &working_dir,
+ Status RunShellCommand(llvm::StringRef command, const FileSpec &working_dir,
int *status_ptr, int *signo_ptr,
std::string *command_output,
const Timeout<std::micro> &timeout) override;
+ Status RunShellCommand(llvm::StringRef interpreter, llvm::StringRef command,
+ const FileSpec &working_dir, int *status_ptr,
+ int *signo_ptr, std::string *command_output,
+ const Timeout<std::micro> &timeout) override;
+
const char *GetHostname() override;
UserIDResolver &GetUserIDResolver() override;
lldb_private::Environment GetEnvironment() override;
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Runtime.h b/contrib/llvm-project/lldb/include/lldb/Target/Runtime.h
new file mode 100644
index 000000000000..06f0b610e40b
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Target/Runtime.h
@@ -0,0 +1,33 @@
+//===-- Runtime.h -----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_RUNTIME_H
+#define LLDB_TARGET_RUNTIME_H
+
+#include "lldb/Target/Process.h"
+
+namespace lldb_private {
+class Runtime {
+public:
+ Runtime(Process *process) : m_process(process) {}
+ virtual ~Runtime() = default;
+ Runtime(const Runtime &) = delete;
+ const Runtime &operator=(const Runtime &) = delete;
+
+ Process *GetProcess() { return m_process; }
+ Target &GetTargetRef() { return m_process->GetTarget(); }
+
+ /// Called when modules have been loaded in the process.
+ virtual void ModulesDidLoad(const ModuleList &module_list) = 0;
+
+protected:
+ Process *m_process;
+};
+} // namespace lldb_private
+
+#endif // LLDB_TARGET_RUNTIME_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/StackFrameRecognizer.h b/contrib/llvm-project/lldb/include/lldb/Target/StackFrameRecognizer.h
index 9c9105ac04e4..baffc890bb06 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/StackFrameRecognizer.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/StackFrameRecognizer.h
@@ -17,6 +17,8 @@
#include "lldb/lldb-private-forward.h"
#include "lldb/lldb-public.h"
+#include <vector>
+
namespace lldb_private {
/// \class RecognizedStackFrame
@@ -95,37 +97,44 @@ private:
operator=(const ScriptedStackFrameRecognizer &) = delete;
};
-/// \class StackFrameRecognizerManager
-///
-/// Static class that provides a registry of known stack frame recognizers.
-/// Has static methods to add, enumerate, remove, query and invoke recognizers.
-
+/// Class that provides a registry of known stack frame recognizers.
class StackFrameRecognizerManager {
public:
- static void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
- ConstString module,
- llvm::ArrayRef<ConstString> symbols,
- bool first_instruction_only = true);
+ void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
+ ConstString module, llvm::ArrayRef<ConstString> symbols,
+ bool first_instruction_only = true);
+
+ void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
+ lldb::RegularExpressionSP module,
+ lldb::RegularExpressionSP symbol,
+ bool first_instruction_only = true);
- static void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
- lldb::RegularExpressionSP module,
- lldb::RegularExpressionSP symbol,
- bool first_instruction_only = true);
+ void ForEach(std::function<
+ void(uint32_t recognizer_id, std::string recognizer_name,
+ std::string module, llvm::ArrayRef<ConstString> symbols,
+ bool regexp)> const &callback);
- static void
- ForEach(std::function<void(uint32_t recognizer_id,
- std::string recognizer_name, std::string module,
- llvm::ArrayRef<ConstString> symbols,
- bool regexp)> const &callback);
+ bool RemoveRecognizerWithID(uint32_t recognizer_id);
- static bool RemoveRecognizerWithID(uint32_t recognizer_id);
+ void RemoveAllRecognizers();
- static void RemoveAllRecognizers();
+ lldb::StackFrameRecognizerSP GetRecognizerForFrame(lldb::StackFrameSP frame);
- static lldb::StackFrameRecognizerSP GetRecognizerForFrame(
- lldb::StackFrameSP frame);
+ lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame);
- static lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame);
+private:
+ struct RegisteredEntry {
+ uint32_t recognizer_id;
+ lldb::StackFrameRecognizerSP recognizer;
+ bool is_regexp;
+ ConstString module;
+ lldb::RegularExpressionSP module_regexp;
+ std::vector<ConstString> symbols;
+ lldb::RegularExpressionSP symbol_regexp;
+ bool first_instruction_only;
+ };
+
+ std::deque<RegisteredEntry> m_recognizers;
};
/// \class ValueObjectRecognizerSynthesizedValue
@@ -145,7 +154,9 @@ class ValueObjectRecognizerSynthesizedValue : public ValueObject {
SetName(parent.GetName());
}
- uint64_t GetByteSize() override { return m_parent->GetByteSize(); }
+ llvm::Optional<uint64_t> GetByteSize() override {
+ return m_parent->GetByteSize();
+ }
lldb::ValueType GetValueType() const override { return m_type; }
bool UpdateValue() override {
if (!m_parent->UpdateValueIfNeeded()) return false;
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/SystemRuntime.h b/contrib/llvm-project/lldb/include/lldb/Target/SystemRuntime.h
index 4f07d7ab52e5..0ec0793e95f9 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/SystemRuntime.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/SystemRuntime.h
@@ -15,6 +15,7 @@
#include "lldb/Core/PluginInterface.h"
#include "lldb/Target/QueueItem.h"
#include "lldb/Target/QueueList.h"
+#include "lldb/Target/Runtime.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/lldb-private.h"
@@ -39,7 +40,7 @@ namespace lldb_private {
/// can be asked to provide that information.
///
-class SystemRuntime : public PluginInterface {
+class SystemRuntime : public Runtime, public PluginInterface {
public:
/// Find a system runtime plugin for a given process.
///
@@ -52,7 +53,7 @@ public:
static SystemRuntime *FindPlugin(Process *process);
/// Construct with a process.
- SystemRuntime(lldb_private::Process *process);
+ SystemRuntime(Process *process);
/// Destructor.
///
@@ -76,7 +77,7 @@ public:
///
/// Allow the SystemRuntime plugin to enable logging features in the system
/// runtime libraries.
- virtual void ModulesDidLoad(lldb_private::ModuleList &module_list);
+ virtual void ModulesDidLoad(const ModuleList &module_list) override;
/// Called before detaching from a process.
///
@@ -294,9 +295,6 @@ public:
}
protected:
- // Member variables.
- Process *m_process;
-
std::vector<ConstString> m_types;
private:
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Target.h b/contrib/llvm-project/lldb/include/lldb/Target/Target.h
index 280ce6359c72..69baefb964b0 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/Target.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/Target.h
@@ -28,6 +28,7 @@
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/PathMappingList.h"
#include "lldb/Target/SectionLoadHistory.h"
+#include "lldb/Target/ThreadSpec.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Broadcaster.h"
#include "lldb/Utility/LLDBAssert.h"
@@ -64,6 +65,12 @@ enum LoadDependentFiles {
eLoadDependentsNo,
};
+enum ImportStdModule {
+ eImportStdModuleFalse,
+ eImportStdModuleFallback,
+ eImportStdModuleTrue,
+};
+
class TargetExperimentalProperties : public Properties {
public:
TargetExperimentalProperties();
@@ -93,6 +100,10 @@ public:
void SetDisableASLR(bool b);
+ bool GetInheritTCC() const;
+
+ void SetInheritTCC(bool b);
+
bool GetDetachOnError() const;
void SetDetachOnError(bool b);
@@ -130,7 +141,7 @@ public:
bool GetEnableAutoImportClangModules() const;
- bool GetEnableImportStdModule() const;
+ ImportStdModule GetImportStdModule() const;
bool GetEnableAutoApplyFixIts() const;
@@ -168,6 +179,8 @@ public:
llvm::StringRef GetExpressionPrefixContents();
+ uint64_t GetExprErrorLimit() const;
+
bool GetUseHexImmediates() const;
bool GetUseFastStepping() const;
@@ -205,7 +218,7 @@ public:
bool GetInjectLocalVariables(ExecutionContext *exe_ctx) const;
void SetInjectLocalVariables(ExecutionContext *exe_ctx, bool b);
-
+
void SetRequireHardwareBreakpoints(bool b);
bool GetRequireHardwareBreakpoints() const;
@@ -214,7 +227,6 @@ public:
void UpdateLaunchInfoFromProperties();
-
private:
// Callbacks for m_launch_info.
void Arg0ValueChangedCallback();
@@ -225,6 +237,7 @@ private:
void ErrorPathValueChangedCallback();
void DetachOnErrorValueChangedCallback();
void DisableASLRValueChangedCallback();
+ void InheritTCCValueChangedCallback();
void DisableSTDIOValueChangedCallback();
Environment ComputeEnvironment() const;
@@ -434,6 +447,7 @@ class Target : public std::enable_shared_from_this<Target>,
public ModuleList::Notifier {
public:
friend class TargetList;
+ friend class Debugger;
/// Broadcaster event bits definitions.
enum {
@@ -503,6 +517,8 @@ public:
static void SetDefaultArchitecture(const ArchSpec &arch);
+ bool IsDummyTarget() const { return m_is_dummy_target; }
+
/// Find a binary on the system and return its Module,
/// or return an existing Module that is already in the Target.
///
@@ -563,7 +579,8 @@ public:
// used.
const lldb::ProcessSP &CreateProcess(lldb::ListenerSP listener_sp,
llvm::StringRef plugin_name,
- const FileSpec *crash_file);
+ const FileSpec *crash_file,
+ bool can_connect);
const lldb::ProcessSP &GetProcessSP() const;
@@ -1064,14 +1081,10 @@ public:
const ValueList &arg_value_list,
const char *name, Status &error);
- // Creates a UtilityFunction for the given language, the rest of the
- // parameters have the same meaning as for the UtilityFunction constructor.
- // Returns a new-ed object which the caller owns.
-
- UtilityFunction *GetUtilityFunctionForLanguage(const char *expr,
- lldb::LanguageType language,
- const char *name,
- Status &error);
+ /// Creates and installs a UtilityFunction for the given language.
+ llvm::Expected<std::unique_ptr<UtilityFunction>>
+ CreateUtilityFunction(std::string expression, std::string name,
+ lldb::LanguageType language, ExecutionContext &exe_ctx);
// Install any files through the platform that need be to installed prior to
// launching or attaching.
@@ -1097,6 +1110,20 @@ public:
void ClearAllLoadedSections();
+ /// Set the \a Trace object containing processor trace information of this
+ /// target.
+ ///
+ /// \param[in] trace_sp
+ /// The trace object.
+ void SetTrace(const lldb::TraceSP &trace_sp);
+
+ /// Get the \a Trace object containing processor trace information of this
+ /// target.
+ ///
+ /// \return
+ /// The trace object. It might be undefined.
+ const lldb::TraceSP &GetTrace();
+
// Since expressions results can persist beyond the lifetime of a process,
// and the const expression results are available after a process is gone, we
// provide a way for expressions to be evaluated from the Target itself. If
@@ -1134,23 +1161,32 @@ public:
class StopHook : public UserID {
public:
StopHook(const StopHook &rhs);
+ virtual ~StopHook() = default;
- ~StopHook();
-
- StringList *GetCommandPointer() { return &m_commands; }
-
- const StringList &GetCommands() { return m_commands; }
+ enum class StopHookKind : uint32_t { CommandBased = 0, ScriptBased };
+ enum class StopHookResult : uint32_t {
+ KeepStopped = 0,
+ RequestContinue,
+ AlreadyContinued
+ };
lldb::TargetSP &GetTarget() { return m_target_sp; }
- void SetCommands(StringList &in_commands) { m_commands = in_commands; }
-
// Set the specifier. The stop hook will own the specifier, and is
// responsible for deleting it when we're done.
void SetSpecifier(SymbolContextSpecifier *specifier);
SymbolContextSpecifier *GetSpecifier() { return m_specifier_sp.get(); }
+ bool ExecutionContextPasses(const ExecutionContext &exe_ctx);
+
+ // Called on stop, this gets passed the ExecutionContext for each "stop
+ // with a reason" thread. It should add to the stream whatever text it
+ // wants to show the user, and return False to indicate it wants the target
+ // not to stop.
+ virtual StopHookResult HandleStop(ExecutionContext &exe_ctx,
+ lldb::StreamSP output) = 0;
+
// Set the Thread Specifier. The stop hook will own the thread specifier,
// and is responsible for deleting it when we're done.
void SetThreadSpecifier(ThreadSpec *specifier);
@@ -1168,28 +1204,84 @@ public:
bool GetAutoContinue() const { return m_auto_continue; }
void GetDescription(Stream *s, lldb::DescriptionLevel level) const;
+ virtual void GetSubclassDescription(Stream *s,
+ lldb::DescriptionLevel level) const = 0;
- private:
+ protected:
lldb::TargetSP m_target_sp;
- StringList m_commands;
lldb::SymbolContextSpecifierSP m_specifier_sp;
std::unique_ptr<ThreadSpec> m_thread_spec_up;
bool m_active = true;
bool m_auto_continue = false;
+ StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid);
+ };
+
+ class StopHookCommandLine : public StopHook {
+ public:
+ virtual ~StopHookCommandLine() = default;
+
+ StringList &GetCommands() { return m_commands; }
+ void SetActionFromString(const std::string &strings);
+ void SetActionFromStrings(const std::vector<std::string> &strings);
+
+ StopHookResult HandleStop(ExecutionContext &exc_ctx,
+ lldb::StreamSP output_sp) override;
+ void GetSubclassDescription(Stream *s,
+ lldb::DescriptionLevel level) const override;
+
+ private:
+ StringList m_commands;
// Use CreateStopHook to make a new empty stop hook. The GetCommandPointer
// and fill it with commands, and SetSpecifier to set the specifier shared
// pointer (can be null, that will match anything.)
- StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid);
+ StopHookCommandLine(lldb::TargetSP target_sp, lldb::user_id_t uid)
+ : StopHook(target_sp, uid) {}
+ friend class Target;
+ };
+
+ class StopHookScripted : public StopHook {
+ public:
+ virtual ~StopHookScripted() = default;
+ StopHookResult HandleStop(ExecutionContext &exc_ctx,
+ lldb::StreamSP output) override;
+
+ Status SetScriptCallback(std::string class_name,
+ StructuredData::ObjectSP extra_args_sp);
+
+ void GetSubclassDescription(Stream *s,
+ lldb::DescriptionLevel level) const override;
+
+ private:
+ std::string m_class_name;
+ /// This holds the dictionary of keys & values that can be used to
+ /// parametrize any given callback's behavior.
+ StructuredDataImpl *m_extra_args; // We own this structured data,
+ // but the SD itself manages the UP.
+ /// This holds the python callback object.
+ StructuredData::GenericSP m_implementation_sp;
+
+ /// Use CreateStopHook to make a new empty stop hook. The GetCommandPointer
+ /// and fill it with commands, and SetSpecifier to set the specifier shared
+ /// pointer (can be null, that will match anything.)
+ StopHookScripted(lldb::TargetSP target_sp, lldb::user_id_t uid)
+ : StopHook(target_sp, uid) {}
friend class Target;
};
+
typedef std::shared_ptr<StopHook> StopHookSP;
- // Add an empty stop hook to the Target's stop hook list, and returns a
- // shared pointer to it in new_hook. Returns the id of the new hook.
- StopHookSP CreateStopHook();
+ /// Add an empty stop hook to the Target's stop hook list, and returns a
+ /// shared pointer to it in new_hook. Returns the id of the new hook.
+ StopHookSP CreateStopHook(StopHook::StopHookKind kind);
+
+ /// If you tried to create a stop hook, and that failed, call this to
+ /// remove the stop hook, as it will also reset the stop hook counter.
+ void UndoCreateStopHook(lldb::user_id_t uid);
- void RunStopHooks();
+ // Runs the stop hooks that have been registered for this target.
+ // Returns true if the stop hooks cause the target to resume.
+ bool RunStopHooks();
size_t GetStopHookSize();
@@ -1251,6 +1343,10 @@ public:
void SetREPL(lldb::LanguageType language, lldb::REPLSP repl_sp);
+ StackFrameRecognizerManager &GetFrameRecognizerManager() {
+ return *m_frame_recognizer_manager_up;
+ }
+
protected:
/// Implementing of ModuleList::Notifier.
@@ -1285,12 +1381,12 @@ protected:
lldb::PlatformSP m_platform_sp; ///< The platform for this target.
std::recursive_mutex m_mutex; ///< An API mutex that is used by the lldb::SB*
/// classes make the SB interface thread safe
- /// When the private state thread calls SB API's - usually because it is
+ /// When the private state thread calls SB API's - usually because it is
/// running OS plugin or Python ThreadPlan code - it should not block on the
/// API mutex that is held by the code that kicked off the sequence of events
- /// that led us to run the code. We hand out this mutex instead when we
+ /// that led us to run the code. We hand out this mutex instead when we
/// detect that code is running on the private state thread.
- std::recursive_mutex m_private_mutex;
+ std::recursive_mutex m_private_mutex;
Arch m_arch;
ModuleList m_images; ///< The list of images for this process (shared
/// libraries and anything dynamically loaded).
@@ -1325,6 +1421,11 @@ protected:
bool m_suppress_stop_hooks;
bool m_is_dummy_target;
unsigned m_next_persistent_variable_index = 0;
+ /// An optional \a lldb_private::Trace object containing processor trace
+ /// information of this target.
+ lldb::TraceSP m_trace_sp;
+ /// Stores the frame recognizers of this target.
+ lldb::StackFrameRecognizerManagerUP m_frame_recognizer_manager_up;
static void ImageSearchPathsChanged(const PathMappingList &path_list,
void *baton);
@@ -1364,7 +1465,7 @@ private:
bool ProcessIsValid();
// Copy breakpoints, stop hooks and so forth from the dummy target:
- void PrimeFromDummyTarget(Target *dummy_target);
+ void PrimeFromDummyTarget(Target &target);
void AddBreakpoint(lldb::BreakpointSP breakpoint_sp, bool internal);
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/TargetList.h b/contrib/llvm-project/lldb/include/lldb/Target/TargetList.h
index 5ed0344f175c..903ca4bcefbc 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/TargetList.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/TargetList.h
@@ -42,8 +42,6 @@ public:
return GetStaticBroadcasterClass();
}
- ~TargetList() override;
-
/// Create a new Target.
///
/// Clients must use this function to create a Target. This allows
@@ -175,7 +173,9 @@ public:
uint32_t SignalIfRunning(lldb::pid_t pid, int signo);
- uint32_t SetSelectedTarget(Target *target);
+ void SetSelectedTarget(uint32_t index);
+
+ void SetSelectedTarget(const lldb::TargetSP &target);
lldb::TargetSP GetSelectedTarget();
@@ -183,28 +183,25 @@ protected:
typedef std::vector<lldb::TargetSP> collection;
// Member variables.
collection m_target_list;
- lldb::TargetSP m_dummy_target_sp;
mutable std::recursive_mutex m_target_list_mutex;
uint32_t m_selected_target_idx;
private:
- lldb::TargetSP GetDummyTarget(lldb_private::Debugger &debugger);
-
- Status CreateDummyTarget(Debugger &debugger,
- llvm::StringRef specified_arch_name,
- lldb::TargetSP &target_sp);
-
- Status CreateTargetInternal(Debugger &debugger, llvm::StringRef user_exe_path,
- llvm::StringRef triple_str,
- LoadDependentFiles load_dependent_files,
- const OptionGroupPlatform *platform_options,
- lldb::TargetSP &target_sp, bool is_dummy_target);
-
- Status CreateTargetInternal(Debugger &debugger, llvm::StringRef user_exe_path,
- const ArchSpec &arch,
- LoadDependentFiles get_dependent_modules,
- lldb::PlatformSP &platform_sp,
- lldb::TargetSP &target_sp, bool is_dummy_target);
+ static Status CreateTargetInternal(
+ Debugger &debugger, llvm::StringRef user_exe_path,
+ llvm::StringRef triple_str, LoadDependentFiles load_dependent_files,
+ const OptionGroupPlatform *platform_options, lldb::TargetSP &target_sp);
+
+ static Status CreateTargetInternal(Debugger &debugger,
+ llvm::StringRef user_exe_path,
+ const ArchSpec &arch,
+ LoadDependentFiles get_dependent_modules,
+ lldb::PlatformSP &platform_sp,
+ lldb::TargetSP &target_sp);
+
+ void AddTargetInternal(lldb::TargetSP target_sp, bool do_select);
+
+ void SetSelectedTargetInternal(uint32_t index);
TargetList(const TargetList &) = delete;
const TargetList &operator=(const TargetList &) = delete;
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Thread.h b/contrib/llvm-project/lldb/include/lldb/Target/Thread.h
index 205a0d965c63..4b148063ec6e 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/Thread.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/Thread.h
@@ -19,6 +19,7 @@
#include "lldb/Target/RegisterCheckpoint.h"
#include "lldb/Target/StackFrameList.h"
#include "lldb/Utility/Broadcaster.h"
+#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/UserID.h"
@@ -253,9 +254,9 @@ public:
bool ThreadStoppedForAReason();
- static const char *RunModeAsCString(lldb::RunMode mode);
+ static std::string RunModeAsString(lldb::RunMode mode);
- static const char *StopReasonAsCString(lldb::StopReason reason);
+ static std::string StopReasonAsString(lldb::StopReason reason);
virtual const char *GetInfo() { return nullptr; }
@@ -468,6 +469,24 @@ public:
// the backing thread for all memory threads each time we stop.
}
+ /// Dump \a count instructions of the thread's \a Trace starting at the \a
+ /// start_position position in reverse order.
+ ///
+ /// The instructions are indexed in reverse order, which means that the \a
+ /// start_position 0 represents the last instruction of the trace
+ /// chronologically.
+ ///
+ /// \param[in] s
+ /// The stream object where the instructions are printed.
+ ///
+ /// \param[in] count
+ /// The number of instructions to print.
+ ///
+ /// \param[in] start_position
+ /// The position of the first instruction to print.
+ void DumpTraceInstructions(Stream &s, size_t count,
+ size_t start_position = 0) const;
+
// If stop_format is true, this will be the form used when we print stop
// info. If false, it will be the form we use for thread list and co.
void DumpUsingSettingsFormat(Stream &strm, uint32_t frame_idx,
@@ -911,6 +930,12 @@ public:
// Thread Plan accessors:
+ /// Format the thread plan information for auto completion.
+ ///
+ /// \param[in] request
+ /// The reference to the completion handler.
+ void AutoCompleteThreadPlans(CompletionRequest &request) const;
+
/// Gets the plan which will execute next on the plan stack.
///
/// \return
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h
index 8c2f9776eeb3..242a4d3c2d6c 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h
@@ -23,310 +23,260 @@
namespace lldb_private {
// ThreadPlan:
+//
// This is the pure virtual base class for thread plans.
//
-// The thread plans provide the "atoms" of behavior that
-// all the logical process control, either directly from commands or through
-// more complex composite plans will rely on.
+// The thread plans provide the "atoms" of behavior that all the logical
+// process control, either directly from commands or through more complex
+// composite plans will rely on.
//
// Plan Stack:
//
-// The thread maintaining a thread plan stack, and you program the actions of a
-// particular thread
-// by pushing plans onto the plan stack.
-// There is always a "Current" plan, which is the top of the plan stack,
-// though in some cases
+// The thread maintaining a thread plan stack, and you program the actions of
+// a particular thread by pushing plans onto the plan stack. There is always
+// a "Current" plan, which is the top of the plan stack, though in some cases
// a plan may defer to plans higher in the stack for some piece of information
// (let us define that the plan stack grows downwards).
//
// The plan stack is never empty, there is always a Base Plan which persists
-// through the life
-// of the running process.
+// through the life of the running process.
//
//
// Creating Plans:
//
-// The thread plan is generally created and added to the plan stack through the
-// QueueThreadPlanFor... API
-// in lldb::Thread. Those API's will return the plan that performs the named
-// operation in a manner
-// appropriate for the current process. The plans in lldb/source/Target are
-// generic
+// The thread plan is generally created and added to the plan stack through
+// the QueueThreadPlanFor... API in lldb::Thread. Those API's will return the
+// plan that performs the named operation in a manner appropriate for the
+// current process. The plans in lldb/source/Target are generic
// implementations, but a Process plugin can override them.
//
// ValidatePlan is then called. If it returns false, the plan is unshipped.
-// This is a little
-// convenience which keeps us from having to error out of the constructor.
+// This is a little convenience which keeps us from having to error out of the
+// constructor.
//
// Then the plan is added to the plan stack. When the plan is added to the
-// plan stack its DidPush
-// will get called. This is useful if a plan wants to push any additional
-// plans as it is constructed,
-// since you need to make sure you're already on the stack before you push
-// additional plans.
+// plan stack its DidPush will get called. This is useful if a plan wants to
+// push any additional plans as it is constructed, since you need to make sure
+// you're already on the stack before you push additional plans.
//
// Completed Plans:
//
-// When the target process stops the plans are queried, among other things, for
-// whether their job is done.
-// If it is they are moved from the plan stack to the Completed Plan stack in
-// reverse order from their position
-// on the plan stack (since multiple plans may be done at a given stop.) This
-// is used primarily so that
-// the lldb::Thread::StopInfo for the thread can be set properly. If one plan
-// pushes another to achieve part of
-// its job, but it doesn't want that sub-plan to be the one that sets the
-// StopInfo, then call SetPrivate on the
-// sub-plan when you create it, and the Thread will pass over that plan in
-// reporting the reason for the stop.
+// When the target process stops the plans are queried, among other things,
+// for whether their job is done. If it is they are moved from the plan stack
+// to the Completed Plan stack in reverse order from their position on the
+// plan stack (since multiple plans may be done at a given stop.) This is
+// used primarily so that the lldb::Thread::StopInfo for the thread can be set
+// properly. If one plan pushes another to achieve part of its job, but it
+// doesn't want that sub-plan to be the one that sets the StopInfo, then call
+// SetPrivate on the sub-plan when you create it, and the Thread will pass
+// over that plan in reporting the reason for the stop.
//
// Discarded plans:
//
// Your plan may also get discarded, i.e. moved from the plan stack to the
-// "discarded plan stack". This can
-// happen, for instance, if the plan is calling a function and the function
-// call crashes and you want
-// to unwind the attempt to call. So don't assume that your plan will always
-// successfully stop. Which leads to:
+// "discarded plan stack". This can happen, for instance, if the plan is
+// calling a function and the function call crashes and you want to unwind the
+// attempt to call. So don't assume that your plan will always successfully
+// stop. Which leads to:
//
// Cleaning up after your plans:
//
// When the plan is moved from the plan stack its WillPop method is always
-// called, no matter why. Once it is
-// moved off the plan stack it is done, and won't get a chance to run again.
-// So you should
-// undo anything that affects target state in this method. But be sure to
-// leave the plan able to correctly
-// fill the StopInfo, however.
-// N.B. Don't wait to do clean up target state till the destructor, since that
-// will usually get called when
+// called, no matter why. Once it is moved off the plan stack it is done, and
+// won't get a chance to run again. So you should undo anything that affects
+// target state in this method. But be sure to leave the plan able to
+// correctly fill the StopInfo, however. N.B. Don't wait to do clean up
+// target state till the destructor, since that will usually get called when
// the target resumes, and you want to leave the target state correct for new
-// plans in the time between when
-// your plan gets unshipped and the next resume.
+// plans in the time between when your plan gets unshipped and the next
+// resume.
//
// Thread State Checkpoint:
//
-// Note that calling functions on target process (ThreadPlanCallFunction) changes
-// current thread state. The function can be called either by direct user demand or
-// internally, for example lldb allocates memory on device to calculate breakpoint
-// condition expression - on Linux it is performed by calling mmap on device.
-// ThreadStateCheckpoint saves Thread state (stop info and completed
-// plan stack) to restore it after completing function call.
+// Note that calling functions on target process (ThreadPlanCallFunction)
+// changes current thread state. The function can be called either by direct
+// user demand or internally, for example lldb allocates memory on device to
+// calculate breakpoint condition expression - on Linux it is performed by
+// calling mmap on device. ThreadStateCheckpoint saves Thread state (stop
+// info and completed plan stack) to restore it after completing function
+// call.
//
// Over the lifetime of the plan, various methods of the ThreadPlan are then
-// called in response to changes of state in
-// the process we are debugging as follows:
+// called in response to changes of state in the process we are debugging as
+// follows:
//
// Resuming:
//
// When the target process is about to be restarted, the plan's WillResume
-// method is called,
-// giving the plan a chance to prepare for the run. If WillResume returns
-// false, then the
-// process is not restarted. Be sure to set an appropriate error value in the
-// Process if
-// you have to do this. Note, ThreadPlans actually implement DoWillResume,
-// WillResume wraps that call.
+// method is called, giving the plan a chance to prepare for the run. If
+// WillResume returns false, then the process is not restarted. Be sure to
+// set an appropriate error value in the Process if you have to do this.
+// Note, ThreadPlans actually implement DoWillResume, WillResume wraps that
+// call.
//
// Next the "StopOthers" method of all the threads are polled, and if one
-// thread's Current plan
-// returns "true" then only that thread gets to run. If more than one returns
-// "true" the threads that want to run solo
-// get run one by one round robin fashion. Otherwise all are let to run.
+// thread's Current plan returns "true" then only that thread gets to run. If
+// more than one returns "true" the threads that want to run solo get run one
+// by one round robin fashion. Otherwise all are let to run.
//
// Note, the way StopOthers is implemented, the base class implementation just
-// asks the previous plan. So if your plan
-// has no opinion about whether it should run stopping others or not, just
-// don't implement StopOthers, and the parent
-// will be asked.
+// asks the previous plan. So if your plan has no opinion about whether it
+// should run stopping others or not, just don't implement StopOthers, and the
+// parent will be asked.
//
// Finally, for each thread that is running, it run state is set to the return
-// of RunState from the
-// thread's Current plan.
+// of RunState from the thread's Current plan.
//
// Responding to a stop:
//
// When the target process stops, the plan is called in the following stages:
//
-// First the thread asks the Current Plan if it can handle this stop by calling
-// PlanExplainsStop.
-// If the Current plan answers "true" then it is asked if the stop should
-// percolate all the way to the
-// user by calling the ShouldStop method. If the current plan doesn't explain
-// the stop, then we query up
-// the plan stack for a plan that does explain the stop. The plan that does
-// explain the stop then needs to
-// figure out what to do about the plans below it in the stack. If the stop is
-// recoverable, then the plan that
-// understands it can just do what it needs to set up to restart, and then
-// continue.
-// Otherwise, the plan that understood the stop should call DiscardPlanStack to
-// clean up the stack below it.
-// Note, plans actually implement DoPlanExplainsStop, the result is cached in
-// PlanExplainsStop so the DoPlanExplainsStop
-// itself will only get called once per stop.
+// First the thread asks the Current Plan if it can handle this stop by
+// calling PlanExplainsStop. If the Current plan answers "true" then it is
+// asked if the stop should percolate all the way to the user by calling the
+// ShouldStop method. If the current plan doesn't explain the stop, then we
+// query up the plan stack for a plan that does explain the stop. The plan
+// that does explain the stop then needs to figure out what to do about the
+// plans below it in the stack. If the stop is recoverable, then the plan
+// that understands it can just do what it needs to set up to restart, and
+// then continue. Otherwise, the plan that understood the stop should call
+// DiscardPlanStack to clean up the stack below it. Note, plans actually
+// implement DoPlanExplainsStop, the result is cached in PlanExplainsStop so
+// the DoPlanExplainsStop itself will only get called once per stop.
//
// Master plans:
//
-// In the normal case, when we decide to stop, we will collapse the plan stack
-// up to the point of the plan that understood
-// the stop reason. However, if a plan wishes to stay on the stack after an
-// event it didn't directly handle
-// it can designate itself a "Master" plan by responding true to IsMasterPlan,
-// and then if it wants not to be
-// discarded, it can return false to OkayToDiscard, and it and all its dependent
-// plans will be preserved when
-// we resume execution.
-//
-// The other effect of being a master plan is that when the Master plan is done
-// , if it has set "OkayToDiscard" to false,
-// then it will be popped & execution will stop and return to the user.
-// Remember that if OkayToDiscard is false, the
-// plan will be popped and control will be given to the next plan above it on
-// the stack So setting OkayToDiscard to
-// false means the user will regain control when the MasterPlan is completed.
-//
-// Between these two controls this allows things like: a MasterPlan/DontDiscard
-// Step Over to hit a breakpoint, stop and
-// return control to the user, but then when the user continues, the step out
-// succeeds.
-// Even more tricky, when the breakpoint is hit, the user can continue to step
-// in/step over/etc, and finally when they
-// continue, they will finish up the Step Over.
+// In the normal case, when we decide to stop, we will collapse the plan
+// stack up to the point of the plan that understood the stop reason.
+// However, if a plan wishes to stay on the stack after an event it didn't
+// directly handle it can designate itself a "Master" plan by responding true
+// to IsMasterPlan, and then if it wants not to be discarded, it can return
+// false to OkayToDiscard, and it and all its dependent plans will be
+// preserved when we resume execution.
+//
+// The other effect of being a master plan is that when the Master plan is
+// done , if it has set "OkayToDiscard" to false, then it will be popped &
+// execution will stop and return to the user. Remember that if OkayToDiscard
+// is false, the plan will be popped and control will be given to the next
+// plan above it on the stack So setting OkayToDiscard to false means the
+// user will regain control when the MasterPlan is completed.
+//
+// Between these two controls this allows things like: a
+// MasterPlan/DontDiscard Step Over to hit a breakpoint, stop and return
+// control to the user, but then when the user continues, the step out
+// succeeds. Even more tricky, when the breakpoint is hit, the user can
+// continue to step in/step over/etc, and finally when they continue, they
+// will finish up the Step Over.
//
// FIXME: MasterPlan & OkayToDiscard aren't really orthogonal. MasterPlan
-// designation means that this plan controls
-// it's fate and the fate of plans below it. OkayToDiscard tells whether the
-// MasterPlan wants to stay on the stack. I
-// originally thought "MasterPlan-ness" would need to be a fixed characteristic
-// of a ThreadPlan, in which case you needed
-// the extra control. But that doesn't seem to be true. So we should be able
-// to convert to only MasterPlan status to mean
-// the current "MasterPlan/DontDiscard". Then no plans would be MasterPlans by
-// default, and you would set the ones you
+// designation means that this plan controls it's fate and the fate of plans
+// below it. OkayToDiscard tells whether the MasterPlan wants to stay on the
+// stack. I originally thought "MasterPlan-ness" would need to be a fixed
+// characteristic of a ThreadPlan, in which case you needed the extra control.
+// But that doesn't seem to be true. So we should be able to convert to only
+// MasterPlan status to mean the current "MasterPlan/DontDiscard". Then no
+// plans would be MasterPlans by default, and you would set the ones you
// wanted to be "user level" in this way.
//
//
// Actually Stopping:
//
// If a plan says responds "true" to ShouldStop, then it is asked if it's job
-// is complete by calling
-// MischiefManaged. If that returns true, the plan is popped from the plan
-// stack and added to the
-// Completed Plan Stack. Then the next plan in the stack is asked if it
-// ShouldStop, and it returns "true",
-// it is asked if it is done, and if yes popped, and so on till we reach a plan
-// that is not done.
-//
-// Since you often know in the ShouldStop method whether your plan is complete,
-// as a convenience you can call
-// SetPlanComplete and the ThreadPlan implementation of MischiefManaged will
-// return "true", without your having
-// to redo the calculation when your sub-classes MischiefManaged is called. If
-// you call SetPlanComplete, you can
-// later use IsPlanComplete to determine whether the plan is complete. This is
-// only a convenience for sub-classes,
+// is complete by calling MischiefManaged. If that returns true, the plan is
+// popped from the plan stack and added to the Completed Plan Stack. Then the
+// next plan in the stack is asked if it ShouldStop, and it returns "true",
+// it is asked if it is done, and if yes popped, and so on till we reach a
+// plan that is not done.
+//
+// Since you often know in the ShouldStop method whether your plan is
+// complete, as a convenience you can call SetPlanComplete and the ThreadPlan
+// implementation of MischiefManaged will return "true", without your having
+// to redo the calculation when your sub-classes MischiefManaged is called.
+// If you call SetPlanComplete, you can later use IsPlanComplete to determine
+// whether the plan is complete. This is only a convenience for sub-classes,
// the logic in lldb::Thread will only call MischiefManaged.
//
-// One slightly tricky point is you have to be careful using SetPlanComplete in
-// PlanExplainsStop because you
-// are not guaranteed that PlanExplainsStop for a plan will get called before
-// ShouldStop gets called. If your sub-plan
+// One slightly tricky point is you have to be careful using SetPlanComplete
+// in PlanExplainsStop because you are not guaranteed that PlanExplainsStop
+// for a plan will get called before ShouldStop gets called. If your sub-plan
// explained the stop and then popped itself, only your ShouldStop will get
// called.
//
-// If ShouldStop for any thread returns "true", then the WillStop method of the
-// Current plan of
-// all threads will be called, the stop event is placed on the Process's public
-// broadcaster, and
-// control returns to the upper layers of the debugger.
+// If ShouldStop for any thread returns "true", then the WillStop method of
+// the Current plan of all threads will be called, the stop event is placed on
+// the Process's public broadcaster, and control returns to the upper layers
+// of the debugger.
//
// Reporting the stop:
//
// When the process stops, the thread is given a StopReason, in the form of a
-// StopInfo object. If there is a completed
-// plan corresponding to the stop, then the "actual" stop reason can be
-// suppressed, and instead a StopInfoThreadPlan
-// object will be cons'ed up from the top completed plan in the stack.
-// However, if the plan doesn't want to be
-// the stop reason, then it can call SetPlanComplete and pass in "false" for
-// the "success" parameter. In that case,
-// the real stop reason will be used instead. One example of this is the
-// "StepRangeStepIn" thread plan. If it stops
-// because of a crash or breakpoint hit, it wants to unship itself, because it
-// isn't so useful to have step in keep going
-// after a breakpoint hit. But it can't be the reason for the stop or no-one
-// would see that they had hit a breakpoint.
+// StopInfo object. If there is a completed plan corresponding to the stop,
+// then the "actual" stop reason can be suppressed, and instead a
+// StopInfoThreadPlan object will be cons'ed up from the top completed plan in
+// the stack. However, if the plan doesn't want to be the stop reason, then
+// it can call SetPlanComplete and pass in "false" for the "success"
+// parameter. In that case, the real stop reason will be used instead. One
+// example of this is the "StepRangeStepIn" thread plan. If it stops because
+// of a crash or breakpoint hit, it wants to unship itself, because it isn't
+// so useful to have step in keep going after a breakpoint hit. But it can't
+// be the reason for the stop or no-one would see that they had hit a
+// breakpoint.
//
// Cleaning up the plan stack:
//
// One of the complications of MasterPlans is that you may get past the limits
-// of a plan without triggering it to clean
-// itself up. For instance, if you are doing a MasterPlan StepOver, and hit a
-// breakpoint in a called function, then
-// step over enough times to step out of the initial StepOver range, each of
-// the step overs will explain the stop &
-// take themselves off the stack, but control would never be returned to the
-// original StepOver. Eventually, the user
-// will continue, and when that continue stops, the old stale StepOver plan
-// that was left on the stack will get woken
-// up and notice it is done. But that can leave junk on the stack for a while.
-// To avoid that, the plans implement a
-// "IsPlanStale" method, that can check whether it is relevant anymore. On
-// stop, after the regular plan negotiation,
-// the remaining plan stack is consulted and if any plan says it is stale, it
-// and the plans below it are discarded from
-// the stack.
+// of a plan without triggering it to clean itself up. For instance, if you
+// are doing a MasterPlan StepOver, and hit a breakpoint in a called function,
+// then step over enough times to step out of the initial StepOver range, each
+// of the step overs will explain the stop & take themselves off the stack,
+// but control would never be returned to the original StepOver. Eventually,
+// the user will continue, and when that continue stops, the old stale
+// StepOver plan that was left on the stack will get woken up and notice it is
+// done. But that can leave junk on the stack for a while. To avoid that, the
+// plans implement a "IsPlanStale" method, that can check whether it is
+// relevant anymore. On stop, after the regular plan negotiation, the
+// remaining plan stack is consulted and if any plan says it is stale, it and
+// the plans below it are discarded from the stack.
//
// Automatically Resuming:
//
// If ShouldStop for all threads returns "false", then the target process will
-// resume. This then cycles back to
-// Resuming above.
+// resume. This then cycles back to Resuming above.
//
// Reporting eStateStopped events when the target is restarted:
//
// If a plan decides to auto-continue the target by returning "false" from
-// ShouldStop, then it will be asked
-// whether the Stopped event should still be reported. For instance, if you
-// hit a breakpoint that is a User set
-// breakpoint, but the breakpoint callback said to continue the target process,
-// you might still want to inform
-// the upper layers of lldb that the stop had happened.
-// The way this works is every thread gets to vote on whether to report the
-// stop. If all votes are eVoteNoOpinion,
-// then the thread list will decide what to do (at present it will pretty much
-// always suppress these stopped events.)
-// If there is an eVoteYes, then the event will be reported regardless of the
-// other votes. If there is an eVoteNo
-// and no eVoteYes's, then the event won't be reported.
+// ShouldStop, then it will be asked whether the Stopped event should still be
+// reported. For instance, if you hit a breakpoint that is a User set
+// breakpoint, but the breakpoint callback said to continue the target
+// process, you might still want to inform the upper layers of lldb that the
+// stop had happened. The way this works is every thread gets to vote on
+// whether to report the stop. If all votes are eVoteNoOpinion, then the
+// thread list will decide what to do (at present it will pretty much always
+// suppress these stopped events.) If there is an eVoteYes, then the event
+// will be reported regardless of the other votes. If there is an eVoteNo and
+// no eVoteYes's, then the event won't be reported.
//
// One other little detail here, sometimes a plan will push another plan onto
-// the plan stack to do some part of
-// the first plan's job, and it would be convenient to tell that plan how it
-// should respond to ShouldReportStop.
+// the plan stack to do some part of the first plan's job, and it would be
+// convenient to tell that plan how it should respond to ShouldReportStop.
// You can do that by setting the stop_vote in the child plan when you create
// it.
//
// Suppressing the initial eStateRunning event:
//
// The private process running thread will take care of ensuring that only one
-// "eStateRunning" event will be
-// delivered to the public Process broadcaster per public eStateStopped event.
-// However there are some cases
-// where the public state of this process is eStateStopped, but a thread plan
-// needs to restart the target, but
-// doesn't want the running event to be publicly broadcast. The obvious
-// example of this is running functions
-// by hand as part of expression evaluation. To suppress the running event
-// return eVoteNo from ShouldReportStop,
-// to force a running event to be reported return eVoteYes, in general though
-// you should return eVoteNoOpinion
-// which will allow the ThreadList to figure out the right thing to do.
-// The run_vote argument to the constructor works like stop_vote, and is a way
-// for a plan to instruct a sub-plan
-// on how to respond to ShouldReportStop.
-//
+// "eStateRunning" event will be delivered to the public Process broadcaster
+// per public eStateStopped event. However there are some cases where the
+// public state of this process is eStateStopped, but a thread plan needs to
+// restart the target, but doesn't want the running event to be publicly
+// broadcast. The obvious example of this is running functions by hand as
+// part of expression evaluation. To suppress the running event return
+// eVoteNo from ShouldReportStop, to force a running event to be reported
+// return eVoteYes, in general though you should return eVoteNoOpinion which
+// will allow the ThreadList to figure out the right thing to do. The
+// run_vote argument to the constructor works like stop_vote, and is a way for
+// a plan to instruct a sub-plan on how to respond to ShouldReportStop.
class ThreadPlan : public std::enable_shared_from_this<ThreadPlan>,
public UserID {
@@ -375,6 +325,12 @@ public:
const Target &GetTarget() const;
+ /// Clear the Thread* cache.
+ ///
+ /// This is useful in situations like when a new Thread list is being
+ /// generated.
+ void ClearThreadCache();
+
/// Print a description of this thread to the stream \a s.
/// \a thread. Don't expect that the result of GetThread is valid in
/// the description method. This might get called when the underlying
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanPython.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanPython.h
index 27bf3a560b1f..7b37b2b9ce5a 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanPython.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanPython.h
@@ -45,7 +45,9 @@ public:
bool WillStop() override;
- bool StopOthers() override;
+ bool StopOthers() override { return m_stop_others; }
+
+ void SetStopOthers(bool new_value) override { m_stop_others = new_value; }
void DidPush() override;
@@ -67,6 +69,7 @@ private:
std::string m_error_str;
StructuredData::ObjectSP m_implementation_sp;
bool m_did_push;
+ bool m_stop_others;
ThreadPlanPython(const ThreadPlanPython &) = delete;
const ThreadPlanPython &operator=(const ThreadPlanPython &) = delete;
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h
index f1874136cad8..7b2817b2e8fd 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h
@@ -35,8 +35,6 @@ public:
ThreadPlanStack(const Thread &thread, bool make_empty = false);
~ThreadPlanStack() {}
- enum StackKind { ePlans, eCompletedPlans, eDiscardedPlans };
-
using PlanStack = std::vector<lldb::ThreadPlanSP>;
void DumpThreadPlans(Stream &s, lldb::DescriptionLevel desc_level,
@@ -95,9 +93,13 @@ public:
void WillResume();
-private:
- const PlanStack &GetStackOfKind(ThreadPlanStack::StackKind kind) const;
+ /// Clear the Thread* cache that each ThreadPlan contains.
+ ///
+ /// This is useful in situations like when a new Thread list is being
+ /// generated.
+ void ClearThreadCache();
+private:
void PrintOneStack(Stream &s, llvm::StringRef stack_name,
const PlanStack &stack, lldb::DescriptionLevel desc_level,
bool include_internal) const;
@@ -145,6 +147,15 @@ public:
return &result->second;
}
+ /// Clear the Thread* cache that each ThreadPlan contains.
+ ///
+ /// This is useful in situations like when a new Thread list is being
+ /// generated.
+ void ClearThreadCache() {
+ for (auto &plan_list : m_plans_list)
+ plan_list.second.ClearThreadCache();
+ }
+
void Clear() {
for (auto plan : m_plans_list)
plan.second.ThreadDestroyed(nullptr);
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInRange.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInRange.h
index 59b5721998b5..a26b0fb87b3a 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInRange.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepInRange.h
@@ -26,13 +26,6 @@ public:
LazyBool step_in_avoids_code_without_debug_info,
LazyBool step_out_avoids_code_without_debug_info);
- ThreadPlanStepInRange(Thread &thread, const AddressRange &range,
- const SymbolContext &addr_context,
- const char *step_into_function_name,
- lldb::RunMode stop_others,
- LazyBool step_in_avoids_code_without_debug_info,
- LazyBool step_out_avoids_code_without_debug_info);
-
~ThreadPlanStepInRange() override;
void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
@@ -78,17 +71,6 @@ protected:
bool FrameMatchesAvoidCriteria();
private:
- friend lldb::ThreadPlanSP Thread::QueueThreadPlanForStepOverRange(
- bool abort_other_plans, const AddressRange &range,
- const SymbolContext &addr_context, lldb::RunMode stop_others,
- Status &status, LazyBool avoid_code_without_debug_info);
- friend lldb::ThreadPlanSP Thread::QueueThreadPlanForStepInRange(
- bool abort_other_plans, const AddressRange &range,
- const SymbolContext &addr_context, const char *step_in_target,
- lldb::RunMode stop_others, Status &status,
- LazyBool step_in_avoids_code_without_debug_info,
- LazyBool step_out_avoids_code_without_debug_info);
-
void SetupAvoidNoDebug(LazyBool step_in_avoids_code_without_debug_info,
LazyBool step_out_avoids_code_without_debug_info);
// Need an appropriate marker for the current stack so we can tell step out
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadTrace.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadTrace.h
new file mode 100644
index 000000000000..a32b33867c26
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadTrace.h
@@ -0,0 +1,61 @@
+//===-- ThreadTrace.h -------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_THREADTRACE_H
+#define LLDB_TARGET_THREADTRACE_H
+
+#include "lldb/Target/Thread.h"
+
+namespace lldb_private {
+
+/// \class ThreadTrace ThreadTrace.h
+///
+/// Thread implementation used for representing threads gotten from trace
+/// session files, which are similar to threads from core files.
+///
+/// See \a TraceSessionFileParser for more information regarding trace session
+/// files.
+class ThreadTrace : public Thread {
+public:
+ /// \param[in] process
+ /// The process who owns this thread.
+ ///
+ /// \param[in] tid
+ /// The tid of this thread.
+ ///
+ /// \param[in] trace_file.
+ /// The file that contains the list of instructions that were traced when
+ /// this thread was being executed.
+ ThreadTrace(Process &process, lldb::tid_t tid, const FileSpec &trace_file)
+ : Thread(process, tid), m_trace_file(trace_file) {}
+
+ void RefreshStateAfterStop() override;
+
+ lldb::RegisterContextSP GetRegisterContext() override;
+
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(StackFrame *frame) override;
+
+ /// \return
+ /// The trace file of this thread.
+ const FileSpec &GetTraceFile() const;
+
+protected:
+ bool CalculateStopInfo() override;
+
+ lldb::RegisterContextSP m_thread_reg_ctx_sp;
+
+private:
+ FileSpec m_trace_file;
+};
+
+typedef std::shared_ptr<ThreadTrace> ThreadTraceSP;
+
+} // namespace lldb_private
+
+#endif // LLDB_TARGET_THREADTRACE_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Trace.h b/contrib/llvm-project/lldb/include/lldb/Target/Trace.h
new file mode 100644
index 000000000000..3b127916a917
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Target/Trace.h
@@ -0,0 +1,203 @@
+//===-- Trace.h -------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_TRACE_H
+#define LLDB_TARGET_TRACE_H
+
+#include "llvm/Support/JSON.h"
+
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/UnimplementedError.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+/// \class Trace Trace.h "lldb/Target/Trace.h"
+/// A plug-in interface definition class for trace information.
+///
+/// Trace plug-ins allow processor trace information to be loaded into LLDB so
+/// that the data can be dumped, used for reverse and forward stepping to allow
+/// introspection into the reason your process crashed or found its way to its
+/// current state.
+///
+/// Trace information can be loaded into a target without a process to allow
+/// introspection of the trace information during post mortem analysis, such as
+/// when loading core files.
+///
+/// Processor trace information can also be fetched through the process
+/// interfaces during a live debug session if your process supports gathering
+/// this information.
+///
+/// In order to support live tracing, the name of the plug-in should match the
+/// name of the tracing type returned by the gdb-remote packet
+/// \a jLLDBTraceSupportedType.
+class Trace : public PluginInterface,
+ public std::enable_shared_from_this<Trace> {
+public:
+ enum class TraceDirection {
+ Forwards = 0,
+ Backwards,
+ };
+
+ /// Dump the trace data that this plug-in has access to.
+ ///
+ /// This function will dump all of the trace data for all threads in a user
+ /// readable format. Options for dumping can be added as this API is iterated
+ /// on.
+ ///
+ /// \param[in] s
+ /// A stream object to dump the information to.
+ virtual void Dump(Stream *s) const = 0;
+
+ /// Find a trace plug-in using JSON data.
+ ///
+ /// When loading trace data from disk, the information for the trace data
+ /// can be contained in multiple files and require plug-in specific
+ /// information about the CPU. Using data like JSON provides an
+ /// easy way to specify all of the settings and information that we will need
+ /// to load trace data into LLDB. This structured data can include:
+ /// - The plug-in name (this allows a specific plug-in to be selected)
+ /// - Architecture or target triple
+ /// - one or more paths to the trace data file on disk
+ /// - core trace data
+ /// - thread events or related information
+ /// - shared library load information to use for this trace data that
+ /// allows a target to be created so the trace information can be
+ /// symbolicated so that the trace information can be displayed to the
+ /// user
+ /// - shared library path
+ /// - load address
+ /// - information on how to fetch the shared library
+ /// - path to locally cached file on disk
+ /// - URL to download the file
+ /// - Any information needed to load the trace file
+ /// - CPU information
+ /// - Custom plug-in information needed to decode the trace information
+ /// correctly.
+ ///
+ /// \param[in] debugger
+ /// The debugger instance where new Targets will be created as part of the
+ /// JSON data parsing.
+ ///
+ /// \param[in] trace_session_file
+ /// The contents of the trace session file describing the trace session.
+ /// See \a TraceSessionFileParser::BuildSchema for more information about
+ /// the schema of this JSON file.
+ ///
+ /// \param[in] session_file_dir
+ /// The path to the directory that contains the session file. It's used to
+ /// resolved relative paths in the session file.
+ static llvm::Expected<lldb::TraceSP>
+ FindPlugin(Debugger &debugger, const llvm::json::Value &trace_session_file,
+ llvm::StringRef session_file_dir);
+
+ /// Get the schema of a Trace plug-in given its name.
+ ///
+ /// \param[in] plugin_name
+ /// Name of the trace plugin.
+ static llvm::Expected<llvm::StringRef>
+ FindPluginSchema(llvm::StringRef plugin_name);
+
+ /// \return
+ /// The JSON schema of this Trace plug-in.
+ virtual llvm::StringRef GetSchema() = 0;
+
+ /// Each decoded thread contains a cursor to the current position the user is
+ /// stopped at. When reverse debugging, each operation like reverse-next or
+ /// reverse-continue will move this cursor, which is then picked by any
+ /// subsequent dump or reverse operation.
+ ///
+ /// The initial position for this cursor is the last element of the thread,
+ /// which is the most recent chronologically.
+ ///
+ /// \return
+ /// The current position of the thread's trace or \b 0 if empty.
+ virtual size_t GetCursorPosition(const Thread &thread) = 0;
+
+ /// Dump \a count instructions of the given thread's trace ending at the
+ /// given \a end_position position.
+ ///
+ /// The instructions are printed along with their indices or positions, which
+ /// are increasing chronologically. This means that the \a index 0 represents
+ /// the oldest instruction of the trace chronologically.
+ ///
+ /// \param[in] thread
+ /// The thread whose trace will be dumped.
+ ///
+ /// \param[in] s
+ /// The stream object where the instructions are printed.
+ ///
+ /// \param[in] count
+ /// The number of instructions to print.
+ ///
+ /// \param[in] end_position
+ /// The position of the last instruction to print.
+ ///
+ /// \param[in] raw
+ /// Dump only instruction addresses without disassembly nor symbol
+ /// information.
+ void DumpTraceInstructions(Thread &thread, Stream &s, size_t count,
+ size_t end_position, bool raw);
+
+ /// Run the provided callback on the instructions of the trace of the given
+ /// thread.
+ ///
+ /// The instructions will be traversed starting at the given \a position
+ /// sequentially until the callback returns \b false, in which case no more
+ /// instructions are inspected.
+ ///
+ /// The purpose of this method is to allow inspecting traced instructions
+ /// without exposing the internal representation of how they are stored on
+ /// memory.
+ ///
+ /// \param[in] thread
+ /// The thread whose trace will be traversed.
+ ///
+ /// \param[in] position
+ /// The instruction position to start iterating on.
+ ///
+ /// \param[in] direction
+ /// If \b TraceDirection::Forwards, then then instructions will be
+ /// traversed forwards chronologically, i.e. with incrementing indices. If
+ /// \b TraceDirection::Backwards, the traversal is done backwards
+ /// chronologically, i.e. with decrementing indices.
+ ///
+ /// \param[in] callback
+ /// The callback to execute on each instruction. If it returns \b false,
+ /// the iteration stops.
+ virtual void TraverseInstructions(
+ const Thread &thread, size_t position, TraceDirection direction,
+ std::function<bool(size_t index, llvm::Expected<lldb::addr_t> load_addr)>
+ callback) = 0;
+
+ /// Stop tracing a live thread
+ ///
+ /// \param[in] thread
+ /// The thread object to stop tracing.
+ ///
+ /// \return
+ /// An \a llvm::Error if stopping tracing failed, or \b
+ /// llvm::Error::success() otherwise.
+ virtual llvm::Error StopTracingThread(const Thread &thread) {
+ return llvm::make_error<UnimplementedError>();
+ }
+
+ /// Get the number of available instructions in the trace of the given thread.
+ ///
+ /// \param[in] thread
+ /// The thread whose trace will be inspected.
+ ///
+ /// \return
+ /// The total number of instructions in the trace.
+ virtual size_t GetInstructionCount(const Thread &thread) = 0;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_TARGET_TRACE_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/TraceSessionFileParser.h b/contrib/llvm-project/lldb/include/lldb/Target/TraceSessionFileParser.h
new file mode 100644
index 000000000000..52cc27c1a485
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Target/TraceSessionFileParser.h
@@ -0,0 +1,179 @@
+//===-- TraceSessionFileParser.h --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_TRACESESSIONPARSER_H
+#define LLDB_TARGET_TRACESESSIONPARSER_H
+
+#include "llvm/Support/JSON.h"
+
+#include "lldb/Target/ThreadTrace.h"
+
+namespace lldb_private {
+
+/// \class TraceSessionFileParser TraceSessionFileParser.h
+///
+/// Base class for parsing the common information of JSON trace session files.
+/// Contains the basic C++ structs that represent the JSON data, which include
+/// \a JSONTraceSession as the root object.
+///
+/// See \a Trace::FindPlugin for more information regarding these JSON files.
+class TraceSessionFileParser {
+public:
+ /// C++ structs representing the JSON trace session.
+ /// \{
+ struct JSONAddress {
+ lldb::addr_t value;
+ };
+
+ struct JSONModule {
+ std::string system_path;
+ llvm::Optional<std::string> file;
+ JSONAddress load_address;
+ llvm::Optional<std::string> uuid;
+ };
+
+ struct JSONThread {
+ int64_t tid;
+ std::string trace_file;
+ };
+
+ struct JSONProcess {
+ int64_t pid;
+ std::string triple;
+ std::vector<JSONThread> threads;
+ std::vector<JSONModule> modules;
+ };
+
+ struct JSONTracePluginSettings {
+ std::string type;
+ };
+
+ struct JSONTraceSessionBase {
+ std::vector<JSONProcess> processes;
+ };
+
+ /// The trace plug-in implementation should provide its own TPluginSettings,
+ /// which corresponds to the "trace" section of the schema.
+ template <class TPluginSettings>
+ struct JSONTraceSession : JSONTraceSessionBase {
+ TPluginSettings trace;
+ };
+ /// \}
+
+ /// Helper struct holding the objects created when parsing a process
+ struct ParsedProcess {
+ lldb::TargetSP target_sp;
+ std::vector<ThreadTraceSP> threads;
+ };
+
+ TraceSessionFileParser(Debugger &debugger, llvm::StringRef session_file_dir,
+ llvm::StringRef schema)
+ : m_debugger(debugger), m_session_file_dir(session_file_dir),
+ m_schema(schema) {}
+
+ /// Build the full schema for a Trace plug-in.
+ ///
+ /// \param[in] plugin_schema
+ /// The subschema that corresponds to the "trace" section of the schema.
+ ///
+ /// \return
+ /// The full schema containing the common attributes and the plug-in
+ /// specific attributes.
+ static std::string BuildSchema(llvm::StringRef plugin_schema);
+
+ /// Parse the fields common to all trace session schemas.
+ ///
+ /// \param[in] session
+ /// The session json objects already deserialized.
+ ///
+ /// \return
+ /// A list of \a ParsedProcess containing all threads and targets created
+ /// during the parsing, or an error in case of failures. In case of
+ /// errors, no side effects are produced.
+ llvm::Expected<std::vector<ParsedProcess>>
+ ParseCommonSessionFile(const JSONTraceSessionBase &session);
+
+protected:
+ /// Resolve non-absolute paths relative to the session file folder. It
+ /// modifies the given file_spec.
+ void NormalizePath(lldb_private::FileSpec &file_spec);
+
+ ThreadTraceSP ParseThread(lldb::ProcessSP &process_sp,
+ const JSONThread &thread);
+
+ llvm::Expected<ParsedProcess> ParseProcess(const JSONProcess &process);
+
+ llvm::Error ParseModule(lldb::TargetSP &target_sp, const JSONModule &module);
+
+ /// Create a user-friendly error message upon a JSON-parsing failure using the
+ /// \a json::ObjectMapper functionality.
+ ///
+ /// \param[in] root
+ /// The \a llvm::json::Path::Root used to parse the JSON \a value.
+ ///
+ /// \param[in] value
+ /// The json value that failed to parse.
+ ///
+ /// \return
+ /// An \a llvm::Error containing the user-friendly error message.
+ llvm::Error CreateJSONError(llvm::json::Path::Root &root,
+ const llvm::json::Value &value);
+
+ Debugger &m_debugger;
+ std::string m_session_file_dir;
+ llvm::StringRef m_schema;
+};
+} // namespace lldb_private
+
+namespace llvm {
+namespace json {
+
+bool fromJSON(const Value &value,
+ lldb_private::TraceSessionFileParser::JSONAddress &address,
+ Path path);
+
+bool fromJSON(const Value &value,
+ lldb_private::TraceSessionFileParser::JSONModule &module,
+ Path path);
+
+bool fromJSON(const Value &value,
+ lldb_private::TraceSessionFileParser::JSONThread &thread,
+ Path path);
+
+bool fromJSON(const Value &value,
+ lldb_private::TraceSessionFileParser::JSONProcess &process,
+ Path path);
+
+bool fromJSON(const Value &value,
+ lldb_private::TraceSessionFileParser::JSONTracePluginSettings
+ &plugin_settings,
+ Path path);
+
+bool fromJSON(
+ const Value &value,
+ lldb_private::TraceSessionFileParser::JSONTraceSessionBase &session,
+ Path path);
+
+template <class TPluginSettings>
+bool fromJSON(
+ const Value &value,
+ lldb_private::TraceSessionFileParser::JSONTraceSession<TPluginSettings>
+ &session,
+ Path path) {
+ ObjectMapper o(value, path);
+ return o && o.map("trace", session.trace) &&
+ fromJSON(value,
+ (lldb_private::TraceSessionFileParser::JSONTraceSessionBase &)
+ session,
+ path);
+}
+
+} // namespace json
+} // namespace llvm
+
+#endif // LLDB_TARGET_TRACESESSIONPARSER_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Target/UnwindAssembly.h b/contrib/llvm-project/lldb/include/lldb/Target/UnwindAssembly.h
index abfd38774399..d20aa52d6f59 100644
--- a/contrib/llvm-project/lldb/include/lldb/Target/UnwindAssembly.h
+++ b/contrib/llvm-project/lldb/include/lldb/Target/UnwindAssembly.h
@@ -20,8 +20,6 @@ class UnwindAssembly : public std::enable_shared_from_this<UnwindAssembly>,
public:
static lldb::UnwindAssemblySP FindPlugin(const ArchSpec &arch);
- ~UnwindAssembly() override;
-
virtual bool
GetNonCallSiteUnwindPlanFromAssembly(AddressRange &func, Thread &thread,
UnwindPlan &unwind_plan) = 0;
@@ -42,11 +40,6 @@ public:
protected:
UnwindAssembly(const ArchSpec &arch);
ArchSpec m_arch;
-
-private:
- UnwindAssembly() = delete;
- UnwindAssembly(const UnwindAssembly &) = delete;
- const UnwindAssembly &operator=(const UnwindAssembly &) = delete;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ArchSpec.h b/contrib/llvm-project/lldb/include/lldb/Utility/ArchSpec.h
index 5466e573c1a5..fdfe6aceb033 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/ArchSpec.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/ArchSpec.h
@@ -92,6 +92,12 @@ public:
eARM_abi_hard_float = 0x00000400
};
+ enum RISCVSubType {
+ eRISCVSubType_unknown,
+ eRISCVSubType_riscv32,
+ eRISCVSubType_riscv64,
+ };
+
enum Core {
eCore_arm_generic,
eCore_arm_armv4,
@@ -125,6 +131,7 @@ public:
eCore_arm_arm64,
eCore_arm_armv8,
eCore_arm_armv8l,
+ eCore_arm_arm64e,
eCore_arm_arm64_32,
eCore_arm_aarch64,
@@ -184,6 +191,9 @@ public:
eCore_hexagon_hexagonv4,
eCore_hexagon_hexagonv5,
+ eCore_riscv32,
+ eCore_riscv64,
+
eCore_uknownMach32,
eCore_uknownMach64,
@@ -505,7 +515,7 @@ public:
void SetFlags(uint32_t flags) { m_flags = flags; }
- void SetFlags(std::string elf_abi);
+ void SetFlags(const std::string &elf_abi);
protected:
bool IsEqualTo(const ArchSpec &rhs, bool exact_match) const;
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Args.h b/contrib/llvm-project/lldb/include/lldb/Utility/Args.h
index 2cce7d0c697c..b93677b53935 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/Args.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/Args.h
@@ -66,6 +66,7 @@ public:
Args(const Args &rhs);
explicit Args(const StringList &list);
+ explicit Args(llvm::ArrayRef<llvm::StringRef> args);
Args &operator=(const Args &rhs);
@@ -262,9 +263,8 @@ public:
static uint32_t StringToGenericRegister(llvm::StringRef s);
- static const char *GetShellSafeArgument(const FileSpec &shell,
- const char *unsafe_arg,
- std::string &safe_arg);
+ static std::string GetShellSafeArgument(const FileSpec &shell,
+ llvm::StringRef unsafe_arg);
// EncodeEscapeSequences will change the textual representation of common
// escape sequences like "\n" (two characters) into a single '\n'. It does
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Broadcaster.h b/contrib/llvm-project/lldb/include/lldb/Utility/Broadcaster.h
index 03995454ecb0..9c025a7c7dd8 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/Broadcaster.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/Broadcaster.h
@@ -39,7 +39,7 @@ namespace lldb_private {
/// Debugger maintains a list of BroadcastEventSpec's and when it is made
class BroadcastEventSpec {
public:
- BroadcastEventSpec(ConstString broadcaster_class, uint32_t event_bits)
+ BroadcastEventSpec(const ConstString &broadcaster_class, uint32_t event_bits)
: m_broadcaster_class(broadcaster_class), m_event_bits(event_bits) {}
~BroadcastEventSpec() = default;
@@ -117,7 +117,7 @@ private:
class BroadcasterClassMatches {
public:
- BroadcasterClassMatches(ConstString broadcaster_class)
+ BroadcasterClassMatches(const ConstString &broadcaster_class)
: m_broadcaster_class(broadcaster_class) {}
~BroadcasterClassMatches() = default;
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h b/contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h
index 1e55b2ebb957..8a67faf5b54a 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h
@@ -42,15 +42,7 @@ public:
/// Default constructor
///
/// Initializes the string to an empty string.
- ConstString() : m_string(nullptr) {}
-
- /// Copy constructor
- ///
- /// Copies the string value in \a rhs into this object.
- ///
- /// \param[in] rhs
- /// Another string object to copy.
- ConstString(const ConstString &rhs) : m_string(rhs.m_string) {}
+ ConstString() = default;
explicit ConstString(const llvm::StringRef &s);
@@ -86,12 +78,6 @@ public:
/// from \a cstr.
explicit ConstString(const char *cstr, size_t max_cstr_len);
- /// Destructor
- ///
- /// Since constant string values are currently not reference counted, there
- /// isn't much to do here.
- ~ConstString() = default;
-
/// C string equality binary predicate function object for ConstString
/// objects.
struct StringIsEqual {
@@ -124,20 +110,6 @@ public:
/// false otherwise.
explicit operator bool() const { return !IsEmpty(); }
- /// Assignment operator
- ///
- /// Assigns the string in this object with the value from \a rhs.
- ///
- /// \param[in] rhs
- /// Another string object to copy into this object.
- ///
- /// \return
- /// A const reference to this object.
- ConstString operator=(ConstString rhs) {
- m_string = rhs.m_string;
- return *this;
- }
-
/// Equal to operator
///
/// Returns true if this string is equal to the string in \a rhs. This
@@ -192,9 +164,7 @@ public:
/// \return
/// \b true if this object is not equal to \a rhs.
/// \b false if this object is equal to \a rhs.
- bool operator!=(ConstString rhs) const {
- return m_string != rhs.m_string;
- }
+ bool operator!=(ConstString rhs) const { return m_string != rhs.m_string; }
/// Not equal to operator against a non-ConstString value.
///
@@ -447,8 +417,7 @@ protected:
return s;
};
- // Member variables
- const char *m_string;
+ const char *m_string = nullptr;
};
/// Stream the string value \a str to the stream \a s
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h b/contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h
index f5749b7e6eaf..2ee706efbea2 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/GDBRemote.h
@@ -10,7 +10,7 @@
#define LLDB_UTILITY_GDBREMOTE_H
#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Reproducer.h"
+#include "lldb/Utility/ReproducerProvider.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-public.h"
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Iterable.h b/contrib/llvm-project/lldb/include/lldb/Utility/Iterable.h
index 3f9b8b1e4c57..5c38e46feb92 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/Iterable.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/Iterable.h
@@ -170,7 +170,7 @@ template <typename C, typename E, E (*A)(typename C::const_iterator &),
typename MutexType>
class LockingAdaptedIterable : public AdaptedIterable<C, E, A> {
public:
- LockingAdaptedIterable(C &container, MutexType &mutex)
+ LockingAdaptedIterable(const C &container, MutexType &mutex)
: AdaptedIterable<C, E, A>(container), m_mutex(&mutex) {
m_mutex->lock();
}
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/OptionDefinition.h b/contrib/llvm-project/lldb/include/lldb/Utility/OptionDefinition.h
new file mode 100644
index 000000000000..082f0f0aa3fa
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/OptionDefinition.h
@@ -0,0 +1,58 @@
+//===-- OptionDefinition.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_UTILITY_OPTIONDEFINITION_H
+#define LLDB_UTILITY_OPTIONDEFINITION_H
+
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-private-types.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/MathExtras.h"
+#include <climits>
+#include <cstdint>
+
+namespace lldb_private {
+struct OptionDefinition {
+ /// Used to mark options that can be used together. If
+ /// `(1 << n & usage_mask) != 0` then this option belongs to option set n.
+ uint32_t usage_mask;
+ /// This option is required (in the current usage level).
+ bool required;
+ /// Full name for this option.
+ const char *long_option;
+ /// Single character for this option. If the option doesn't use a short
+ /// option character, this has to be a integer value that is not a printable
+ /// ASCII code point and also unique in the used set of options.
+ /// @see OptionDefinition::HasShortOption
+ int short_option;
+ /// no_argument, required_argument or optional_argument
+ int option_has_arg;
+ /// If non-NULL, option is valid iff |validator->IsValid()|, otherwise
+ /// always valid.
+ OptionValidator *validator;
+ /// If not empty, an array of enum values.
+ OptionEnumValues enum_values;
+ /// The kind of completion for this option.
+ /// Contains values of the CommandCompletions::CommonCompletionTypes enum.
+ uint32_t completion_type;
+ /// Type of argument this option takes.
+ lldb::CommandArgumentType argument_type;
+ /// Full text explaining what this options does and what (if any) argument to
+ /// pass it.
+ const char *usage_text;
+
+ /// Whether this has a short option character.
+ bool HasShortOption() const {
+ // See the short_option documentation for more.
+ return llvm::isUInt<CHAR_BIT>(short_option) &&
+ llvm::isPrint(short_option);
+ }
+};
+} // namespace lldb_private
+
+#endif // LLDB_UTILITY_OPTIONDEFINITION_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h b/contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h
index ec91060cda54..8f5a5f6d21fb 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/ProcessInfo.h
@@ -14,7 +14,6 @@
#include "lldb/Utility/Environment.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/NameMatches.h"
-#include "lldb/Utility/Reproducer.h"
#include "llvm/Support/YAMLTraits.h"
#include <vector>
@@ -217,40 +216,7 @@ protected:
};
namespace repro {
-class ProcessInfoRecorder : public AbstractRecorder {
-public:
- ProcessInfoRecorder(const FileSpec &filename, std::error_code &ec)
- : AbstractRecorder(filename, ec) {}
-
- static llvm::Expected<std::unique_ptr<ProcessInfoRecorder>>
- Create(const FileSpec &filename);
-
- void Record(const ProcessInstanceInfoList &process_infos);
-};
-
-class ProcessInfoProvider : public repro::Provider<ProcessInfoProvider> {
-public:
- struct Info {
- static const char *name;
- static const char *file;
- };
-
- ProcessInfoProvider(const FileSpec &directory) : Provider(directory) {}
-
- ProcessInfoRecorder *GetNewProcessInfoRecorder();
-
- void Keep() override;
- void Discard() override;
-
- static char ID;
-
-private:
- std::unique_ptr<llvm::raw_fd_ostream> m_stream_up;
- std::vector<std::unique_ptr<ProcessInfoRecorder>> m_process_info_recorders;
-};
-
llvm::Optional<ProcessInstanceInfoList> GetReplayProcessInstanceInfoList();
-
} // namespace repro
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/RangeMap.h b/contrib/llvm-project/lldb/include/lldb/Utility/RangeMap.h
index fb24c5a43479..118fdfd85fa9 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/RangeMap.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/RangeMap.h
@@ -194,41 +194,25 @@ public:
#ifdef ASSERT_RANGEMAP_ARE_SORTED
assert(IsSorted());
#endif
- // Can't combine if ranges if we have zero or one range
- if (m_entries.size() > 1) {
- // The list should be sorted prior to calling this function
- typename Collection::iterator pos;
- typename Collection::iterator end;
- typename Collection::iterator prev;
- bool can_combine = false;
- // First we determine if we can combine any of the Entry objects so we
- // don't end up allocating and making a new collection for no reason
- for (pos = m_entries.begin(), end = m_entries.end(), prev = end;
- pos != end; prev = pos++) {
- if (prev != end && prev->DoesAdjoinOrIntersect(*pos)) {
- can_combine = true;
- break;
- }
- }
+ auto first_intersect = std::adjacent_find(
+ m_entries.begin(), m_entries.end(), [](const Entry &a, const Entry &b) {
+ return a.DoesAdjoinOrIntersect(b);
+ });
+ if (first_intersect == m_entries.end())
+ return;
- // We we can combine at least one entry, then we make a new collection
- // and populate it accordingly, and then swap it into place.
- if (can_combine) {
- Collection minimal_ranges;
- for (pos = m_entries.begin(), end = m_entries.end(), prev = end;
- pos != end; prev = pos++) {
- if (prev != end && prev->DoesAdjoinOrIntersect(*pos))
- minimal_ranges.back().SetRangeEnd(
- std::max<BaseType>(prev->GetRangeEnd(), pos->GetRangeEnd()));
- else
- minimal_ranges.push_back(*pos);
- }
- // Use the swap technique in case our new vector is much smaller. We
- // must swap when using the STL because std::vector objects never
- // release or reduce the memory once it has been allocated/reserved.
- m_entries.swap(minimal_ranges);
- }
+ // We we can combine at least one entry, then we make a new collection and
+ // populate it accordingly, and then swap it into place.
+ auto pos = std::next(first_intersect);
+ Collection minimal_ranges(m_entries.begin(), pos);
+ for (; pos != m_entries.end(); ++pos) {
+ Entry &back = minimal_ranges.back();
+ if (back.DoesAdjoinOrIntersect(*pos))
+ back.SetRangeEnd(std::max(back.GetRangeEnd(), pos->GetRangeEnd()));
+ else
+ minimal_ranges.push_back(*pos);
}
+ m_entries.swap(minimal_ranges);
}
BaseType GetMinRangeBase(BaseType fail_value) const {
@@ -353,6 +337,10 @@ public:
return nullptr;
}
+ using const_iterator = typename Collection::const_iterator;
+ const_iterator begin() const { return m_entries.begin(); }
+ const_iterator end() const { return m_entries.end(); }
+
protected:
void CombinePrevAndNext(typename Collection::iterator pos) {
// Check if the prev or next entries in case they need to be unioned with
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/RegisterValue.h b/contrib/llvm-project/lldb/include/lldb/Utility/RegisterValue.h
index c9f295a8d95a..4211b0a59992 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/RegisterValue.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/RegisterValue.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/StringRef.h"
#include <cstdint>
#include <cstring>
+#include <utility>
namespace lldb_private {
class DataExtractor;
@@ -60,7 +61,7 @@ public:
}
explicit RegisterValue(llvm::APInt inst) : m_type(eTypeUInt128) {
- m_scalar = llvm::APInt(inst);
+ m_scalar = llvm::APInt(std::move(inst));
}
explicit RegisterValue(float value) : m_type(eTypeFloat) { m_scalar = value; }
@@ -73,9 +74,9 @@ public:
m_scalar = value;
}
- explicit RegisterValue(uint8_t *bytes, size_t length,
+ explicit RegisterValue(llvm::ArrayRef<uint8_t> bytes,
lldb::ByteOrder byte_order) {
- SetBytes(bytes, length, byte_order);
+ SetBytes(bytes.data(), bytes.size(), byte_order);
}
RegisterValue::Type GetType() const { return m_type; }
@@ -169,7 +170,7 @@ public:
void operator=(llvm::APInt uint) {
m_type = eTypeUInt128;
- m_scalar = llvm::APInt(uint);
+ m_scalar = llvm::APInt(std::move(uint));
}
void operator=(float f) {
@@ -209,7 +210,7 @@ public:
void SetUInt128(llvm::APInt uint) {
m_type = eTypeUInt128;
- m_scalar = uint;
+ m_scalar = std::move(uint);
}
bool SetUInt(uint64_t uint, uint32_t byte_size);
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Reproducer.h b/contrib/llvm-project/lldb/include/lldb/Utility/Reproducer.h
index ab673e5e0019..4659254e57d6 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/Reproducer.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/Reproducer.h
@@ -11,15 +11,18 @@
#include "lldb/Utility/FileSpec.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
-#include "llvm/Support/FileCollector.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/YAMLTraits.h"
#include <mutex>
#include <string>
+#include <utility>
#include <vector>
namespace lldb_private {
+class UUID;
namespace repro {
class Reproducer;
@@ -82,211 +85,6 @@ protected:
using ProviderBase::ProviderBase; // Inherit constructor.
};
-class FileProvider : public Provider<FileProvider> {
-public:
- struct Info {
- static const char *name;
- static const char *file;
- };
-
- FileProvider(const FileSpec &directory)
- : Provider(directory),
- m_collector(std::make_shared<llvm::FileCollector>(
- directory.CopyByAppendingPathComponent("root").GetPath(),
- directory.GetPath())) {}
-
- std::shared_ptr<llvm::FileCollector> GetFileCollector() {
- return m_collector;
- }
-
- void recordInterestingDirectory(const llvm::Twine &dir);
-
- void Keep() override {
- auto mapping = GetRoot().CopyByAppendingPathComponent(Info::file);
- // Temporary files that are removed during execution can cause copy errors.
- if (auto ec = m_collector->copyFiles(/*stop_on_error=*/false))
- return;
- m_collector->writeMapping(mapping.GetPath());
- }
-
- static char ID;
-
-private:
- std::shared_ptr<llvm::FileCollector> m_collector;
-};
-
-/// Provider for the LLDB version number.
-///
-/// When the reproducer is kept, it writes the lldb version to a file named
-/// version.txt in the reproducer root.
-class VersionProvider : public Provider<VersionProvider> {
-public:
- VersionProvider(const FileSpec &directory) : Provider(directory) {}
- struct Info {
- static const char *name;
- static const char *file;
- };
- void SetVersion(std::string version) {
- assert(m_version.empty());
- m_version = std::move(version);
- }
- void Keep() override;
- std::string m_version;
- static char ID;
-};
-
-/// Provider for the LLDB current working directory.
-///
-/// When the reproducer is kept, it writes lldb's current working directory to
-/// a file named cwd.txt in the reproducer root.
-class WorkingDirectoryProvider : public Provider<WorkingDirectoryProvider> {
-public:
- WorkingDirectoryProvider(const FileSpec &directory) : Provider(directory) {
- llvm::SmallString<128> cwd;
- if (std::error_code EC = llvm::sys::fs::current_path(cwd))
- return;
- m_cwd = std::string(cwd.str());
- }
-
- void Update(llvm::StringRef path) { m_cwd = std::string(path); }
-
- struct Info {
- static const char *name;
- static const char *file;
- };
- void Keep() override;
- std::string m_cwd;
- static char ID;
-};
-
-/// The recorder is a small object handed out by a provider to record data. It
-/// is commonly used in combination with a MultiProvider which is meant to
-/// record information for multiple instances of the same source of data.
-class AbstractRecorder {
-protected:
- AbstractRecorder(const FileSpec &filename, std::error_code &ec)
- : m_filename(filename.GetFilename().GetStringRef()),
- m_os(filename.GetPath(), ec, llvm::sys::fs::OF_Text), m_record(true) {}
-
-public:
- const FileSpec &GetFilename() { return m_filename; }
-
- void Stop() {
- assert(m_record);
- m_record = false;
- }
-
-private:
- FileSpec m_filename;
-
-protected:
- llvm::raw_fd_ostream m_os;
- bool m_record;
-};
-
-/// Recorder that records its data as text to a file.
-class DataRecorder : public AbstractRecorder {
-public:
- DataRecorder(const FileSpec &filename, std::error_code &ec)
- : AbstractRecorder(filename, ec) {}
-
- static llvm::Expected<std::unique_ptr<DataRecorder>>
- Create(const FileSpec &filename);
-
- template <typename T> void Record(const T &t, bool newline = false) {
- if (!m_record)
- return;
- m_os << t;
- if (newline)
- m_os << '\n';
- m_os.flush();
- }
-};
-
-/// Recorder that records its data as YAML to a file.
-class YamlRecorder : public AbstractRecorder {
-public:
- YamlRecorder(const FileSpec &filename, std::error_code &ec)
- : AbstractRecorder(filename, ec) {}
-
- static llvm::Expected<std::unique_ptr<YamlRecorder>>
- Create(const FileSpec &filename);
-
- template <typename T> void Record(const T &t) {
- if (!m_record)
- return;
- llvm::yaml::Output yout(m_os);
- // The YAML traits are defined as non-const because they are used for
- // serialization and deserialization. The cast is safe because
- // serialization doesn't modify the object.
- yout << const_cast<T &>(t);
- m_os.flush();
- }
-};
-
-/// The MultiProvider is a provider that hands out recorder which can be used
-/// to capture data for different instances of the same object. The recorders
-/// can be passed around or stored as an instance member.
-///
-/// The Info::file for the MultiProvider contains an index of files for every
-/// recorder. Use the MultiLoader to read the index and get the individual
-/// files.
-template <typename T, typename V>
-class MultiProvider : public repro::Provider<V> {
-public:
- MultiProvider(const FileSpec &directory) : Provider<V>(directory) {}
-
- T *GetNewRecorder() {
- std::size_t i = m_recorders.size() + 1;
- std::string filename = (llvm::Twine(V::Info::name) + llvm::Twine("-") +
- llvm::Twine(i) + llvm::Twine(".yaml"))
- .str();
- auto recorder_or_error =
- T::Create(this->GetRoot().CopyByAppendingPathComponent(filename));
- if (!recorder_or_error) {
- llvm::consumeError(recorder_or_error.takeError());
- return nullptr;
- }
-
- m_recorders.push_back(std::move(*recorder_or_error));
- return m_recorders.back().get();
- }
-
- void Keep() override {
- std::vector<std::string> files;
- for (auto &recorder : m_recorders) {
- recorder->Stop();
- files.push_back(recorder->GetFilename().GetPath());
- }
-
- FileSpec file = this->GetRoot().CopyByAppendingPathComponent(V::Info::file);
- std::error_code ec;
- llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
- if (ec)
- return;
- llvm::yaml::Output yout(os);
- yout << files;
- }
-
- void Discard() override { m_recorders.clear(); }
-
-private:
- std::vector<std::unique_ptr<T>> m_recorders;
-};
-
-class CommandProvider : public MultiProvider<DataRecorder, CommandProvider> {
-public:
- struct Info {
- static const char *name;
- static const char *file;
- };
-
- CommandProvider(const FileSpec &directory)
- : MultiProvider<DataRecorder, CommandProvider>(directory) {}
-
- static char ID;
-};
-
/// The generator is responsible for the logic needed to generate a
/// reproducer. For doing so it relies on providers, who serialize data that
/// is necessary for reproducing a failure.
@@ -399,6 +197,7 @@ public:
static Reproducer &Instance();
static llvm::Error Initialize(ReproducerMode mode,
llvm::Optional<FileSpec> root);
+ static void Initialize();
static bool Initialized();
static void Terminate();
@@ -428,51 +227,25 @@ private:
mutable std::mutex m_mutex;
};
-/// Loader for data captured with the MultiProvider. It will read the index and
-/// return the path to the files in the index.
-template <typename T> class MultiLoader {
+class Verifier {
public:
- MultiLoader(std::vector<std::string> files) : m_files(files) {}
-
- static std::unique_ptr<MultiLoader> Create(Loader *loader) {
- if (!loader)
- return {};
-
- FileSpec file = loader->GetFile<typename T::Info>();
- if (!file)
- return {};
-
- auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath());
- if (auto err = error_or_file.getError())
- return {};
-
- std::vector<std::string> files;
- llvm::yaml::Input yin((*error_or_file)->getBuffer());
- yin >> files;
-
- if (auto err = yin.error())
- return {};
-
- for (auto &file : files) {
- FileSpec absolute_path =
- loader->GetRoot().CopyByAppendingPathComponent(file);
- file = absolute_path.GetPath();
- }
-
- return std::make_unique<MultiLoader<T>>(std::move(files));
- }
-
- llvm::Optional<std::string> GetNextFile() {
- if (m_index >= m_files.size())
- return {};
- return m_files[m_index++];
- }
+ Verifier(Loader *loader) : m_loader(loader) {}
+ void Verify(llvm::function_ref<void(llvm::StringRef)> error_callback,
+ llvm::function_ref<void(llvm::StringRef)> warning_callback,
+ llvm::function_ref<void(llvm::StringRef)> note_callback) const;
private:
- std::vector<std::string> m_files;
- unsigned m_index = 0;
+ Loader *m_loader;
};
+struct ReplayOptions {
+ bool verify = true;
+ bool check_version = true;
+};
+
+llvm::Error Finalize(Loader *loader);
+llvm::Error Finalize(const FileSpec &root);
+
} // namespace repro
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h b/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h
index 5fc33ad1a17b..c8a98adf85c7 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h
@@ -17,6 +17,7 @@
#include "llvm/Support/ErrorHandling.h"
#include <map>
+#include <thread>
#include <type_traits>
template <typename T,
@@ -78,6 +79,13 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) {
// is initialized or enabled.
// #define LLDB_REPRO_INSTR_TRACE
+#ifdef LLDB_REPRO_INSTR_TRACE
+inline llvm::raw_ostream &this_thread_id() {
+ size_t tid = std::hash<std::thread::id>{}(std::this_thread::get_id());
+ return llvm::errs().write_hex(tid) << " :: ";
+}
+#endif
+
#define LLDB_REGISTER_CONSTRUCTOR(Class, Signature) \
R.Register<Class * Signature>(&construct<Class Signature>::record, "", \
#Class, #Class, #Signature)
@@ -325,6 +333,7 @@ public:
}
template <typename T> const T &HandleReplayResult(const T &t) {
+ CheckSequence(Deserialize<unsigned>());
unsigned result = Deserialize<unsigned>();
if (is_trivially_serializable<T>::value)
return t;
@@ -334,6 +343,7 @@ public:
/// Store the returned value in the index-to-object mapping.
template <typename T> T &HandleReplayResult(T &t) {
+ CheckSequence(Deserialize<unsigned>());
unsigned result = Deserialize<unsigned>();
if (is_trivially_serializable<T>::value)
return t;
@@ -343,6 +353,7 @@ public:
/// Store the returned value in the index-to-object mapping.
template <typename T> T *HandleReplayResult(T *t) {
+ CheckSequence(Deserialize<unsigned>());
unsigned result = Deserialize<unsigned>();
if (is_trivially_serializable<T>::value)
return t;
@@ -352,6 +363,7 @@ public:
/// All returned types are recorded, even when the function returns a void.
/// The latter requires special handling.
void HandleReplayResultVoid() {
+ CheckSequence(Deserialize<unsigned>());
unsigned result = Deserialize<unsigned>();
assert(result == 0);
(void)result;
@@ -361,6 +373,10 @@ public:
return m_index_to_object.GetAllObjects();
}
+ void SetExpectedSequence(unsigned sequence) {
+ m_expected_sequence = sequence;
+ }
+
private:
template <typename T> T Read(ValueTag) {
assert(HasData(sizeof(T)));
@@ -402,11 +418,17 @@ private:
return *(new UnderlyingT(Deserialize<UnderlyingT>()));
}
+ /// Verify that the given sequence number matches what we expect.
+ void CheckSequence(unsigned sequence);
+
/// Mapping of indices to objects.
IndexToObject m_index_to_object;
/// Buffer containing the serialized data.
llvm::StringRef m_buffer;
+
+ /// The result's expected sequence number.
+ llvm::Optional<unsigned> m_expected_sequence;
};
/// Partial specialization for C-style strings. We read the string value
@@ -600,8 +622,8 @@ private:
/// objects (in which case we serialize their index).
template <typename T> void Serialize(T *t) {
#ifdef LLDB_REPRO_INSTR_TRACE
- llvm::errs() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> "
- << stringify_args(t) << "\n";
+ this_thread_id() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> "
+ << stringify_args(t) << "\n";
#endif
if (std::is_fundamental<T>::value) {
Serialize(*t);
@@ -616,8 +638,8 @@ private:
/// to objects (in which case we serialize their index).
template <typename T> void Serialize(T &t) {
#ifdef LLDB_REPRO_INSTR_TRACE
- llvm::errs() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> "
- << stringify_args(t) << "\n";
+ this_thread_id() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> "
+ << stringify_args(t) << "\n";
#endif
if (is_trivially_serializable<T>::value) {
m_stream.write(reinterpret_cast<const char *>(&t), sizeof(T));
@@ -637,8 +659,8 @@ private:
void Serialize(const char *t) {
#ifdef LLDB_REPRO_INSTR_TRACE
- llvm::errs() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> "
- << stringify_args(t) << "\n";
+ this_thread_id() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> "
+ << stringify_args(t) << "\n";
#endif
const size_t size = t ? strlen(t) : std::numeric_limits<size_t>::max();
Serialize(size);
@@ -737,12 +759,15 @@ public:
if (!ShouldCapture())
return;
+ std::lock_guard<std::mutex> lock(g_mutex);
+ unsigned sequence = GetSequenceNumber();
unsigned id = registry.GetID(uintptr_t(f));
#ifdef LLDB_REPRO_INSTR_TRACE
Log(id);
#endif
+ serializer.SerializeAll(sequence);
serializer.SerializeAll(id);
serializer.SerializeAll(args...);
@@ -750,6 +775,7 @@ public:
typename std::remove_reference<Result>::type>::type>::value) {
m_result_recorded = false;
} else {
+ serializer.SerializeAll(sequence);
serializer.SerializeAll(0);
m_result_recorded = true;
}
@@ -763,16 +789,20 @@ public:
if (!ShouldCapture())
return;
+ std::lock_guard<std::mutex> lock(g_mutex);
+ unsigned sequence = GetSequenceNumber();
unsigned id = registry.GetID(uintptr_t(f));
#ifdef LLDB_REPRO_INSTR_TRACE
Log(id);
#endif
+ serializer.SerializeAll(sequence);
serializer.SerializeAll(id);
serializer.SerializeAll(args...);
// Record result.
+ serializer.SerializeAll(sequence);
serializer.SerializeAll(0);
m_result_recorded = true;
}
@@ -798,7 +828,9 @@ public:
if (update_boundary)
UpdateBoundary();
if (m_serializer && ShouldCapture()) {
+ std::lock_guard<std::mutex> lock(g_mutex);
assert(!m_result_recorded);
+ m_serializer->SerializeAll(GetSequenceNumber());
m_serializer->SerializeAll(r);
m_result_recorded = true;
}
@@ -808,6 +840,7 @@ public:
template <typename Result, typename T>
Result Replay(Deserializer &deserializer, Registry &registry, uintptr_t addr,
bool update_boundary) {
+ deserializer.SetExpectedSequence(deserializer.Deserialize<unsigned>());
unsigned actual_id = registry.GetID(addr);
unsigned id = deserializer.Deserialize<unsigned>();
registry.CheckID(id, actual_id);
@@ -818,6 +851,7 @@ public:
}
void Replay(Deserializer &deserializer, Registry &registry, uintptr_t addr) {
+ deserializer.SetExpectedSequence(deserializer.Deserialize<unsigned>());
unsigned actual_id = registry.GetID(addr);
unsigned id = deserializer.Deserialize<unsigned>();
registry.CheckID(id, actual_id);
@@ -833,7 +867,14 @@ public:
bool ShouldCapture() { return m_local_boundary; }
+ /// Mark the current thread as a private thread and pretend that everything
+ /// on this thread is behind happening behind the API boundary.
+ static void PrivateThread() { g_global_boundary = true; }
+
private:
+ static unsigned GetNextSequenceNumber() { return g_sequence++; }
+ unsigned GetSequenceNumber() const;
+
template <typename T> friend struct replay;
void UpdateBoundary() {
if (m_local_boundary)
@@ -842,8 +883,8 @@ private:
#ifdef LLDB_REPRO_INSTR_TRACE
void Log(unsigned id) {
- llvm::errs() << "Recording " << id << ": " << m_pretty_func << " ("
- << m_pretty_args << ")\n";
+ this_thread_id() << "Recording " << id << ": " << m_pretty_func << " ("
+ << m_pretty_args << ")\n";
}
#endif
@@ -859,8 +900,17 @@ private:
/// Whether the return value was recorded explicitly.
bool m_result_recorded;
+ /// The sequence number for this pair of function and result.
+ unsigned m_sequence;
+
/// Whether we're currently across the API boundary.
- static bool g_global_boundary;
+ static thread_local bool g_global_boundary;
+
+ /// Global mutex to protect concurrent access.
+ static std::mutex g_mutex;
+
+ /// Unique, monotonically increasing sequence number.
+ static std::atomic<unsigned> g_sequence;
};
/// To be used as the "Runtime ID" of a constructor. It also invokes the
@@ -1002,6 +1052,7 @@ struct invoke_char_ptr<Result (Class::*)(Args...) const> {
static Result replay(Recorder &recorder, Deserializer &deserializer,
Registry &registry, char *str) {
+ deserializer.SetExpectedSequence(deserializer.Deserialize<unsigned>());
deserializer.Deserialize<unsigned>();
Class *c = deserializer.Deserialize<Class *>();
deserializer.Deserialize<const char *>();
@@ -1023,6 +1074,7 @@ struct invoke_char_ptr<Result (Class::*)(Args...)> {
static Result replay(Recorder &recorder, Deserializer &deserializer,
Registry &registry, char *str) {
+ deserializer.SetExpectedSequence(deserializer.Deserialize<unsigned>());
deserializer.Deserialize<unsigned>();
Class *c = deserializer.Deserialize<Class *>();
deserializer.Deserialize<const char *>();
@@ -1043,6 +1095,7 @@ struct invoke_char_ptr<Result (*)(Args...)> {
static Result replay(Recorder &recorder, Deserializer &deserializer,
Registry &registry, char *str) {
+ deserializer.SetExpectedSequence(deserializer.Deserialize<unsigned>());
deserializer.Deserialize<unsigned>();
deserializer.Deserialize<const char *>();
size_t l = deserializer.Deserialize<size_t>();
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerProvider.h b/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerProvider.h
new file mode 100644
index 000000000000..221c0eb9c5bb
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerProvider.h
@@ -0,0 +1,434 @@
+//===-- Reproducer.h --------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_UTILITY_REPRODUCER_PROVIDER_H
+#define LLDB_UTILITY_REPRODUCER_PROVIDER_H
+
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/ProcessInfo.h"
+#include "lldb/Utility/Reproducer.h"
+#include "lldb/Utility/UUID.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileCollector.h"
+#include "llvm/Support/YAMLTraits.h"
+
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace lldb_private {
+namespace repro {
+
+/// The recorder is a small object handed out by a provider to record data. It
+/// is commonly used in combination with a MultiProvider which is meant to
+/// record information for multiple instances of the same source of data.
+class AbstractRecorder {
+protected:
+ AbstractRecorder(const FileSpec &filename, std::error_code &ec)
+ : m_filename(filename.GetFilename().GetStringRef()),
+ m_os(filename.GetPath(), ec, llvm::sys::fs::OF_Text), m_record(true) {}
+
+public:
+ const FileSpec &GetFilename() { return m_filename; }
+
+ void Stop() {
+ assert(m_record);
+ m_record = false;
+ }
+
+private:
+ FileSpec m_filename;
+
+protected:
+ llvm::raw_fd_ostream m_os;
+ bool m_record;
+};
+
+/// Recorder that records its data as text to a file.
+class DataRecorder : public AbstractRecorder {
+public:
+ DataRecorder(const FileSpec &filename, std::error_code &ec)
+ : AbstractRecorder(filename, ec) {}
+
+ static llvm::Expected<std::unique_ptr<DataRecorder>>
+ Create(const FileSpec &filename);
+
+ template <typename T> void Record(const T &t, bool newline = false) {
+ if (!m_record)
+ return;
+ m_os << t;
+ if (newline)
+ m_os << '\n';
+ m_os.flush();
+ }
+};
+
+/// Recorder that records its data as YAML to a file.
+class YamlRecorder : public AbstractRecorder {
+public:
+ YamlRecorder(const FileSpec &filename, std::error_code &ec)
+ : AbstractRecorder(filename, ec) {}
+
+ static llvm::Expected<std::unique_ptr<YamlRecorder>>
+ Create(const FileSpec &filename);
+
+ template <typename T> void Record(const T &t) {
+ if (!m_record)
+ return;
+ llvm::yaml::Output yout(m_os);
+ // The YAML traits are defined as non-const because they are used for
+ // serialization and deserialization. The cast is safe because
+ // serialization doesn't modify the object.
+ yout << const_cast<T &>(t);
+ m_os.flush();
+ }
+};
+
+class FlushingFileCollector : public llvm::FileCollectorBase {
+public:
+ FlushingFileCollector(llvm::StringRef files_path, llvm::StringRef dirs_path,
+ std::error_code &ec);
+
+protected:
+ void addFileImpl(llvm::StringRef file) override;
+
+ llvm::vfs::directory_iterator
+ addDirectoryImpl(const llvm::Twine &dir,
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,
+ std::error_code &dir_ec) override;
+
+ llvm::Optional<llvm::raw_fd_ostream> m_files_os;
+ llvm::Optional<llvm::raw_fd_ostream> m_dirs_os;
+};
+
+class FileProvider : public Provider<FileProvider> {
+public:
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+
+ FileProvider(const FileSpec &directory) : Provider(directory) {
+ std::error_code ec;
+ m_collector = std::make_shared<FlushingFileCollector>(
+ directory.CopyByAppendingPathComponent("files.txt").GetPath(),
+ directory.CopyByAppendingPathComponent("dirs.txt").GetPath(), ec);
+ if (ec)
+ m_collector.reset();
+ }
+
+ std::shared_ptr<llvm::FileCollectorBase> GetFileCollector() {
+ return m_collector;
+ }
+
+ void RecordInterestingDirectory(const llvm::Twine &dir);
+ void RecordInterestingDirectoryRecursive(const llvm::Twine &dir);
+
+ static char ID;
+
+private:
+ std::shared_ptr<FlushingFileCollector> m_collector;
+};
+
+/// Provider for the LLDB version number.
+///
+/// When the reproducer is kept, it writes the lldb version to a file named
+/// version.txt in the reproducer root.
+class VersionProvider : public Provider<VersionProvider> {
+public:
+ VersionProvider(const FileSpec &directory) : Provider(directory) {}
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+ void SetVersion(std::string version) {
+ assert(m_version.empty());
+ m_version = std::move(version);
+ }
+ void Keep() override;
+ std::string m_version;
+ static char ID;
+};
+
+/// Abstract provider to storing directory paths.
+template <typename T> class DirectoryProvider : public repro::Provider<T> {
+public:
+ DirectoryProvider(const FileSpec &root) : Provider<T>(root) {}
+ void SetDirectory(std::string directory) {
+ m_directory = std::move(directory);
+ }
+ llvm::StringRef GetDirectory() { return m_directory; }
+
+ void Keep() override {
+ FileSpec file = this->GetRoot().CopyByAppendingPathComponent(T::Info::file);
+ std::error_code ec;
+ llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
+ if (ec)
+ return;
+ os << m_directory << "\n";
+ }
+
+protected:
+ std::string m_directory;
+};
+
+/// Provider for the current working directory.
+///
+/// When the reproducer is kept, it writes lldb's current working directory to
+/// a file named cwd.txt in the reproducer root.
+class WorkingDirectoryProvider
+ : public DirectoryProvider<WorkingDirectoryProvider> {
+public:
+ WorkingDirectoryProvider(const FileSpec &directory)
+ : DirectoryProvider(directory) {
+ llvm::SmallString<128> cwd;
+ if (std::error_code EC = llvm::sys::fs::current_path(cwd))
+ return;
+ SetDirectory(std::string(cwd));
+ }
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+ static char ID;
+};
+
+/// Provider for the home directory.
+///
+/// When the reproducer is kept, it writes the user's home directory to a file
+/// a file named home.txt in the reproducer root.
+class HomeDirectoryProvider : public DirectoryProvider<HomeDirectoryProvider> {
+public:
+ HomeDirectoryProvider(const FileSpec &directory)
+ : DirectoryProvider(directory) {
+ llvm::SmallString<128> home_dir;
+ llvm::sys::path::home_directory(home_dir);
+ SetDirectory(std::string(home_dir));
+ }
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+ static char ID;
+};
+
+/// Provider for mapping UUIDs to symbol and executable files.
+class SymbolFileProvider : public Provider<SymbolFileProvider> {
+public:
+ SymbolFileProvider(const FileSpec &directory)
+ : Provider(directory), m_symbol_files() {}
+
+ void AddSymbolFile(const UUID *uuid, const FileSpec &module_path,
+ const FileSpec &symbol_path);
+ void Keep() override;
+
+ struct Entry {
+ Entry() = default;
+ Entry(std::string uuid) : uuid(std::move(uuid)) {}
+ Entry(std::string uuid, std::string module_path, std::string symbol_path)
+ : uuid(std::move(uuid)), module_path(std::move(module_path)),
+ symbol_path(std::move(symbol_path)) {}
+
+ bool operator==(const Entry &rhs) const { return uuid == rhs.uuid; }
+ bool operator<(const Entry &rhs) const { return uuid < rhs.uuid; }
+
+ std::string uuid;
+ std::string module_path;
+ std::string symbol_path;
+ };
+
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+ static char ID;
+
+private:
+ std::vector<Entry> m_symbol_files;
+};
+
+/// The MultiProvider is a provider that hands out recorder which can be used
+/// to capture data for different instances of the same object. The recorders
+/// can be passed around or stored as an instance member.
+///
+/// The Info::file for the MultiProvider contains an index of files for every
+/// recorder. Use the MultiLoader to read the index and get the individual
+/// files.
+template <typename T, typename V>
+class MultiProvider : public repro::Provider<V> {
+public:
+ MultiProvider(const FileSpec &directory) : Provider<V>(directory) {}
+
+ T *GetNewRecorder() {
+ std::size_t i = m_recorders.size() + 1;
+ std::string filename = (llvm::Twine(V::Info::name) + llvm::Twine("-") +
+ llvm::Twine(i) + llvm::Twine(".yaml"))
+ .str();
+ auto recorder_or_error =
+ T::Create(this->GetRoot().CopyByAppendingPathComponent(filename));
+ if (!recorder_or_error) {
+ llvm::consumeError(recorder_or_error.takeError());
+ return nullptr;
+ }
+
+ m_recorders.push_back(std::move(*recorder_or_error));
+ return m_recorders.back().get();
+ }
+
+ void Keep() override {
+ std::vector<std::string> files;
+ for (auto &recorder : m_recorders) {
+ recorder->Stop();
+ files.push_back(recorder->GetFilename().GetPath());
+ }
+
+ FileSpec file = this->GetRoot().CopyByAppendingPathComponent(V::Info::file);
+ std::error_code ec;
+ llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
+ if (ec)
+ return;
+ llvm::yaml::Output yout(os);
+ yout << files;
+ }
+
+ void Discard() override { m_recorders.clear(); }
+
+private:
+ std::vector<std::unique_ptr<T>> m_recorders;
+};
+
+class CommandProvider : public MultiProvider<DataRecorder, CommandProvider> {
+public:
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+
+ CommandProvider(const FileSpec &directory)
+ : MultiProvider<DataRecorder, CommandProvider>(directory) {}
+
+ static char ID;
+};
+
+class ProcessInfoRecorder : public AbstractRecorder {
+public:
+ ProcessInfoRecorder(const FileSpec &filename, std::error_code &ec)
+ : AbstractRecorder(filename, ec) {}
+
+ static llvm::Expected<std::unique_ptr<ProcessInfoRecorder>>
+ Create(const FileSpec &filename);
+
+ void Record(const ProcessInstanceInfoList &process_infos);
+};
+
+class ProcessInfoProvider : public repro::Provider<ProcessInfoProvider> {
+public:
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+
+ ProcessInfoProvider(const FileSpec &directory) : Provider(directory) {}
+
+ ProcessInfoRecorder *GetNewProcessInfoRecorder();
+
+ void Keep() override;
+ void Discard() override;
+
+ static char ID;
+
+private:
+ std::unique_ptr<llvm::raw_fd_ostream> m_stream_up;
+ std::vector<std::unique_ptr<ProcessInfoRecorder>> m_process_info_recorders;
+};
+
+/// Loader for data captured with the MultiProvider. It will read the index and
+/// return the path to the files in the index.
+template <typename T> class MultiLoader {
+public:
+ MultiLoader(std::vector<std::string> files) : m_files(std::move(files)) {}
+
+ static std::unique_ptr<MultiLoader> Create(Loader *loader) {
+ if (!loader)
+ return {};
+
+ FileSpec file = loader->GetFile<typename T::Info>();
+ if (!file)
+ return {};
+
+ auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath());
+ if (auto err = error_or_file.getError())
+ return {};
+
+ std::vector<std::string> files;
+ llvm::yaml::Input yin((*error_or_file)->getBuffer());
+ yin >> files;
+
+ if (auto err = yin.error())
+ return {};
+
+ for (auto &file : files) {
+ FileSpec absolute_path =
+ loader->GetRoot().CopyByAppendingPathComponent(file);
+ file = absolute_path.GetPath();
+ }
+
+ return std::make_unique<MultiLoader<T>>(std::move(files));
+ }
+
+ llvm::Optional<std::string> GetNextFile() {
+ if (m_index >= m_files.size())
+ return {};
+ return m_files[m_index++];
+ }
+
+private:
+ std::vector<std::string> m_files;
+ unsigned m_index = 0;
+};
+
+class SymbolFileLoader {
+public:
+ SymbolFileLoader(Loader *loader);
+ std::pair<FileSpec, FileSpec> GetPaths(const UUID *uuid) const;
+
+private:
+ // Sorted list of UUID to path mappings.
+ std::vector<SymbolFileProvider::Entry> m_symbol_files;
+};
+
+/// Helper to read directories written by the DirectoryProvider.
+template <typename T>
+llvm::Expected<std::string> GetDirectoryFrom(repro::Loader *loader) {
+ llvm::Expected<std::string> dir = loader->LoadBuffer<T>();
+ if (!dir)
+ return dir.takeError();
+ return std::string(llvm::StringRef(*dir).rtrim());
+}
+
+} // namespace repro
+} // namespace lldb_private
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::repro::SymbolFileProvider::Entry)
+
+namespace llvm {
+namespace yaml {
+template <>
+struct MappingTraits<lldb_private::repro::SymbolFileProvider::Entry> {
+ static void mapping(IO &io,
+ lldb_private::repro::SymbolFileProvider::Entry &entry) {
+ io.mapRequired("uuid", entry.uuid);
+ io.mapRequired("module-path", entry.module_path);
+ io.mapRequired("symbol-path", entry.symbol_path);
+ }
+};
+} // namespace yaml
+} // namespace llvm
+
+#endif // LLDB_UTILITY_REPRODUCER_PROVIDER_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Scalar.h b/contrib/llvm-project/lldb/include/lldb/Utility/Scalar.h
index f215fa71c84c..f797aaf99626 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/Scalar.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/Scalar.h
@@ -9,94 +9,68 @@
#ifndef LLDB_UTILITY_SCALAR_H
#define LLDB_UTILITY_SCALAR_H
+#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-private-types.h"
-#include "lldb/Utility/LLDBAssert.h"
#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
#include <cstddef>
#include <cstdint>
+#include <utility>
namespace lldb_private {
+
class DataExtractor;
class Stream;
-} // namespace lldb_private
#define NUM_OF_WORDS_INT128 2
#define BITWIDTH_INT128 128
-#define NUM_OF_WORDS_INT256 4
-#define BITWIDTH_INT256 256
-#define NUM_OF_WORDS_INT512 8
-#define BITWIDTH_INT512 512
-
-namespace lldb_private {
// A class designed to hold onto values and their corresponding types.
// Operators are defined and Scalar objects will correctly promote their types
// and values before performing these operations. Type promotion currently
// follows the ANSI C type promotion rules.
class Scalar {
+ template<typename T>
+ static llvm::APSInt MakeAPSInt(T v) {
+ static_assert(std::is_integral<T>::value, "");
+ static_assert(sizeof(T) <= sizeof(uint64_t), "Conversion loses precision!");
+ return llvm::APSInt(
+ llvm::APInt(sizeof(T) * 8, uint64_t(v), std::is_signed<T>::value),
+ std::is_unsigned<T>::value);
+ }
+
public:
- // FIXME: These are host types which seems to be an odd choice.
enum Type {
e_void = 0,
- e_sint,
- e_uint,
- e_slong,
- e_ulong,
- e_slonglong,
- e_ulonglong,
- e_sint128,
- e_uint128,
- e_sint256,
- e_uint256,
- e_sint512,
- e_uint512,
+ e_int,
e_float,
- e_double,
- e_long_double
};
// Constructors and Destructors
- Scalar();
- Scalar(int v) : m_type(e_sint), m_float(static_cast<float>(0)) {
- m_integer = llvm::APInt(sizeof(int) * 8, v, true);
- }
- Scalar(unsigned int v) : m_type(e_uint), m_float(static_cast<float>(0)) {
- m_integer = llvm::APInt(sizeof(int) * 8, v);
- }
- Scalar(long v) : m_type(e_slong), m_float(static_cast<float>(0)) {
- m_integer = llvm::APInt(sizeof(long) * 8, v, true);
- }
- Scalar(unsigned long v) : m_type(e_ulong), m_float(static_cast<float>(0)) {
- m_integer = llvm::APInt(sizeof(long) * 8, v);
- }
- Scalar(long long v) : m_type(e_slonglong), m_float(static_cast<float>(0)) {
- m_integer = llvm::APInt(sizeof(long long) * 8, v, true);
- }
+ Scalar() : m_type(e_void), m_float(0.0f) {}
+ Scalar(int v) : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
+ Scalar(unsigned int v)
+ : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
+ Scalar(long v) : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
+ Scalar(unsigned long v)
+ : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
+ Scalar(long long v)
+ : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
Scalar(unsigned long long v)
- : m_type(e_ulonglong), m_float(static_cast<float>(0)) {
- m_integer = llvm::APInt(sizeof(long long) * 8, v);
- }
- Scalar(float v) : m_type(e_float), m_float(v) { m_float = llvm::APFloat(v); }
- Scalar(double v) : m_type(e_double), m_float(v) {
- m_float = llvm::APFloat(v);
+ : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
+ Scalar(float v) : m_type(e_float), m_float(v) {}
+ Scalar(double v) : m_type(e_float), m_float(v) {}
+ Scalar(long double v) : m_type(e_float), m_float(double(v)) {
+ bool ignore;
+ m_float.convert(llvm::APFloat::x87DoubleExtended(),
+ llvm::APFloat::rmNearestTiesToEven, &ignore);
}
- Scalar(long double v)
- : m_type(e_long_double),
- m_float(llvm::APFloat::x87DoubleExtended(),
- llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
- (reinterpret_cast<type128 *>(&v))->x)) {}
- Scalar(llvm::APInt v) : m_type(), m_float(static_cast<float>(0)) {
- m_integer = llvm::APInt(v);
- m_type = GetBestTypeForBitSize(m_integer.getBitWidth(), true);
- }
- // Scalar(const RegisterValue& reg_value);
- virtual ~Scalar();
-
- /// Return the most efficient Scalar::Type for the requested bit size.
- static Type GetBestTypeForBitSize(size_t bit_size, bool sign);
+ Scalar(llvm::APInt v)
+ : m_type(e_int), m_integer(std::move(v), false), m_float(0.0f) {}
+ Scalar(llvm::APSInt v)
+ : m_type(e_int), m_integer(std::move(v)), m_float(0.0f) {}
bool SignExtend(uint32_t bit_pos);
@@ -129,34 +103,26 @@ public:
void GetValue(Stream *s, bool show_type) const;
- bool IsValid() const {
- return (m_type >= e_sint) && (m_type <= e_long_double);
- }
+ bool IsValid() const { return (m_type >= e_int) && (m_type <= e_float); }
/// Convert to an integer with \p bits and the given signedness.
void TruncOrExtendTo(uint16_t bits, bool sign);
- bool Promote(Scalar::Type type);
+ bool IntegralPromote(uint16_t bits, bool sign);
+ bool FloatPromote(const llvm::fltSemantics &semantics);
+ bool IsSigned() const;
bool MakeSigned();
bool MakeUnsigned();
static const char *GetValueTypeAsCString(Scalar::Type value_type);
- static Scalar::Type
- GetValueTypeForSignedIntegerWithByteSize(size_t byte_size);
-
- static Scalar::Type
- GetValueTypeForUnsignedIntegerWithByteSize(size_t byte_size);
-
- static Scalar::Type GetValueTypeForFloatWithByteSize(size_t byte_size);
-
// All operators can benefits from the implicit conversions that will happen
// automagically by the compiler, so no temporary objects will need to be
// created. As a result, we currently don't need a variety of overloaded set
// value accessors.
- Scalar &operator+=(const Scalar &rhs);
+ Scalar &operator+=(Scalar rhs);
Scalar &operator<<=(const Scalar &rhs); // Shift left
Scalar &operator>>=(const Scalar &rhs); // Shift right (arithmetic)
Scalar &operator&=(const Scalar &rhs);
@@ -217,72 +183,37 @@ public:
Status SetValueFromCString(const char *s, lldb::Encoding encoding,
size_t byte_size);
- Status SetValueFromData(DataExtractor &data, lldb::Encoding encoding,
+ Status SetValueFromData(const DataExtractor &data, lldb::Encoding encoding,
size_t byte_size);
- static bool UIntValueIsValidForSize(uint64_t uval64, size_t total_byte_size) {
- if (total_byte_size > 8)
- return false;
-
- if (total_byte_size == 8)
- return true;
-
- const uint64_t max = (static_cast<uint64_t>(1)
- << static_cast<uint64_t>(total_byte_size * 8)) -
- 1;
- return uval64 <= max;
- }
-
- static bool SIntValueIsValidForSize(int64_t sval64, size_t total_byte_size) {
- if (total_byte_size > 8)
- return false;
-
- if (total_byte_size == 8)
- return true;
-
- const int64_t max = (static_cast<int64_t>(1)
- << static_cast<uint64_t>(total_byte_size * 8 - 1)) -
- 1;
- const int64_t min = ~(max);
- return min <= sval64 && sval64 <= max;
- }
-
protected:
- typedef char schar_t;
- typedef unsigned char uchar_t;
- typedef short sshort_t;
- typedef unsigned short ushort_t;
- typedef int sint_t;
- typedef unsigned int uint_t;
- typedef long slong_t;
- typedef unsigned long ulong_t;
- typedef long long slonglong_t;
- typedef unsigned long long ulonglong_t;
- typedef float float_t;
- typedef double double_t;
- typedef long double long_double_t;
-
- // Classes that inherit from Scalar can see and modify these
Scalar::Type m_type;
- llvm::APInt m_integer;
+ llvm::APSInt m_integer;
llvm::APFloat m_float;
template <typename T> T GetAs(T fail_value) const;
+ static Type PromoteToMaxType(Scalar &lhs, Scalar &rhs);
+
+ using PromotionKey = std::tuple<Type, unsigned, bool>;
+ PromotionKey GetPromoKey() const;
+
+ static PromotionKey GetFloatPromoKey(const llvm::fltSemantics &semantics);
+
private:
friend const Scalar operator+(const Scalar &lhs, const Scalar &rhs);
- friend const Scalar operator-(const Scalar &lhs, const Scalar &rhs);
- friend const Scalar operator/(const Scalar &lhs, const Scalar &rhs);
- friend const Scalar operator*(const Scalar &lhs, const Scalar &rhs);
- friend const Scalar operator&(const Scalar &lhs, const Scalar &rhs);
- friend const Scalar operator|(const Scalar &lhs, const Scalar &rhs);
- friend const Scalar operator%(const Scalar &lhs, const Scalar &rhs);
- friend const Scalar operator^(const Scalar &lhs, const Scalar &rhs);
+ friend const Scalar operator-(Scalar lhs, Scalar rhs);
+ friend const Scalar operator/(Scalar lhs, Scalar rhs);
+ friend const Scalar operator*(Scalar lhs, Scalar rhs);
+ friend const Scalar operator&(Scalar lhs, Scalar rhs);
+ friend const Scalar operator|(Scalar lhs, Scalar rhs);
+ friend const Scalar operator%(Scalar lhs, Scalar rhs);
+ friend const Scalar operator^(Scalar lhs, Scalar rhs);
friend const Scalar operator<<(const Scalar &lhs, const Scalar &rhs);
friend const Scalar operator>>(const Scalar &lhs, const Scalar &rhs);
- friend bool operator==(const Scalar &lhs, const Scalar &rhs);
+ friend bool operator==(Scalar lhs, Scalar rhs);
friend bool operator!=(const Scalar &lhs, const Scalar &rhs);
- friend bool operator<(const Scalar &lhs, const Scalar &rhs);
+ friend bool operator<(Scalar lhs, Scalar rhs);
friend bool operator<=(const Scalar &lhs, const Scalar &rhs);
friend bool operator>(const Scalar &lhs, const Scalar &rhs);
friend bool operator>=(const Scalar &lhs, const Scalar &rhs);
@@ -302,18 +233,18 @@ private:
// Differentiate among members functions, non-member functions, and
// friend functions
const Scalar operator+(const Scalar &lhs, const Scalar &rhs);
-const Scalar operator-(const Scalar &lhs, const Scalar &rhs);
-const Scalar operator/(const Scalar &lhs, const Scalar &rhs);
-const Scalar operator*(const Scalar &lhs, const Scalar &rhs);
-const Scalar operator&(const Scalar &lhs, const Scalar &rhs);
-const Scalar operator|(const Scalar &lhs, const Scalar &rhs);
-const Scalar operator%(const Scalar &lhs, const Scalar &rhs);
-const Scalar operator^(const Scalar &lhs, const Scalar &rhs);
+const Scalar operator-(Scalar lhs, Scalar rhs);
+const Scalar operator/(Scalar lhs, Scalar rhs);
+const Scalar operator*(Scalar lhs, Scalar rhs);
+const Scalar operator&(Scalar lhs, Scalar rhs);
+const Scalar operator|(Scalar lhs, Scalar rhs);
+const Scalar operator%(Scalar lhs, Scalar rhs);
+const Scalar operator^(Scalar lhs, Scalar rhs);
const Scalar operator<<(const Scalar &lhs, const Scalar &rhs);
const Scalar operator>>(const Scalar &lhs, const Scalar &rhs);
-bool operator==(const Scalar &lhs, const Scalar &rhs);
+bool operator==(Scalar lhs, Scalar rhs);
bool operator!=(const Scalar &lhs, const Scalar &rhs);
-bool operator<(const Scalar &lhs, const Scalar &rhs);
+bool operator<(Scalar lhs, Scalar rhs);
bool operator<=(const Scalar &lhs, const Scalar &rhs);
bool operator>(const Scalar &lhs, const Scalar &rhs);
bool operator>=(const Scalar &lhs, const Scalar &rhs);
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h b/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h
index 715f3cb2541d..3b6ed8030985 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h
@@ -76,6 +76,7 @@ public:
eServerPacketType_QSetSTDERR,
eServerPacketType_QSetWorkingDir,
eServerPacketType_QStartNoAckMode,
+ eServerPacketType_qPathComplete,
eServerPacketType_qPlatform_shell,
eServerPacketType_qPlatform_mkdir,
eServerPacketType_qPlatform_chmod,
@@ -161,11 +162,13 @@ public:
eServerPacketType__m,
eServerPacketType_notify, // '%' notification
- eServerPacketType_jTraceStart,
- eServerPacketType_jTraceBufferRead,
- eServerPacketType_jTraceMetaRead,
- eServerPacketType_jTraceStop,
- eServerPacketType_jTraceConfigRead,
+ eServerPacketType_jTraceStart, // deprecated
+ eServerPacketType_jTraceBufferRead, // deprecated
+ eServerPacketType_jTraceMetaRead, // deprecated
+ eServerPacketType_jTraceStop, // deprecated
+ eServerPacketType_jTraceConfigRead, // deprecated
+
+ eServerPacketType_jLLDBTraceSupportedType,
};
ServerPacketType GetServerPacketType() const;
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StringList.h b/contrib/llvm-project/lldb/include/lldb/Utility/StringList.h
index 591a15861593..34930abeac3c 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/StringList.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/StringList.h
@@ -102,7 +102,7 @@ public:
StringList &operator<<(const std::string &s);
- StringList &operator<<(StringList strings);
+ StringList &operator<<(const StringList &strings);
// Copy assignment for a vector of strings
StringList &operator=(const std::vector<std::string> &rhs);
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h b/contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h
index 14c82e669676..4d03af18e527 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h
@@ -271,9 +271,9 @@ public:
return false;
}
- void Push(ObjectSP item) { m_items.push_back(item); }
+ void Push(const ObjectSP &item) { m_items.push_back(item); }
- void AddItem(ObjectSP item) { m_items.push_back(item); }
+ void AddItem(const ObjectSP &item) { m_items.push_back(item); }
void Serialize(llvm::json::OStream &s) const override;
@@ -493,7 +493,7 @@ public:
void AddItem(llvm::StringRef key, ObjectSP value_sp) {
ConstString key_cs(key);
- m_dict[key_cs] = value_sp;
+ m_dict[key_cs] = std::move(value_sp);
}
void AddIntegerItem(llvm::StringRef key, uint64_t value) {
@@ -547,7 +547,7 @@ public:
void *m_object;
};
- static ObjectSP ParseJSON(std::string json_text);
+ static ObjectSP ParseJSON(const std::string &json_text);
static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error);
};
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Timer.h b/contrib/llvm-project/lldb/include/lldb/Utility/Timer.h
index f97315b2db0f..edc064b23b57 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/Timer.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/Timer.h
@@ -25,6 +25,7 @@ public:
class Category {
public:
explicit Category(const char *category_name);
+ llvm::StringRef GetName() { return m_name; }
private:
friend class Timer;
@@ -73,4 +74,11 @@ private:
} // namespace lldb_private
+#define LLDB_SCOPED_TIMER() \
+ static ::lldb_private::Timer::Category _cat(LLVM_PRETTY_FUNCTION); \
+ ::lldb_private::Timer _scoped_timer(_cat, LLVM_PRETTY_FUNCTION)
+#define LLDB_SCOPED_TIMERF(...) \
+ static ::lldb_private::Timer::Category _cat(LLVM_PRETTY_FUNCTION); \
+ ::lldb_private::Timer _scoped_timer(_cat, __VA_ARGS__)
+
#endif // LLDB_UTILITY_TIMER_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/TraceOptions.h b/contrib/llvm-project/lldb/include/lldb/Utility/TraceOptions.h
index 97aad33899be..c9a8d12ce125 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/TraceOptions.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/TraceOptions.h
@@ -15,6 +15,19 @@
#include "lldb/Utility/StructuredData.h"
namespace lldb_private {
+
+/// This struct represents a tracing technology.
+struct TraceTypeInfo {
+ /// The name of the technology, e.g. intel-pt or arm-coresight.
+ ///
+ /// In order for a Trace plug-in (see \a lldb_private::Trace.h) to support the
+ /// trace technology given by this struct, it should match its name with this
+ /// field.
+ std::string name;
+ /// A description for the technology.
+ std::string description;
+};
+
class TraceOptions {
public:
TraceOptions() : m_trace_params(new StructuredData::Dictionary()) {}
@@ -57,4 +70,12 @@ private:
};
}
+namespace llvm {
+namespace json {
+
+bool fromJSON(const Value &value, lldb_private::TraceTypeInfo &info, Path path);
+
+} // namespace json
+} // namespace llvm
+
#endif // LLDB_UTILITY_TRACEOPTIONS_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/UUID.h b/contrib/llvm-project/lldb/include/lldb/Utility/UUID.h
index 5327719094c0..f2107d9b135b 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/UUID.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/UUID.h
@@ -11,6 +11,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Endian.h"
#include <stddef.h>
#include <stdint.h>
#include <string>
@@ -23,6 +24,22 @@ class UUID {
public:
UUID() = default;
+ // Reference:
+ // https://crashpad.chromium.org/doxygen/structcrashpad_1_1CodeViewRecordPDB70.html
+ struct CvRecordPdb70 {
+ struct {
+ llvm::support::ulittle32_t Data1;
+ llvm::support::ulittle16_t Data2;
+ llvm::support::ulittle16_t Data3;
+ uint8_t Data4[8];
+ } Uuid;
+ llvm::support::ulittle32_t Age;
+ // char PDBFileName[];
+ };
+
+ /// Create a UUID from CvRecordPdb70.
+ static UUID fromCvRecord(CvRecordPdb70 debug_info);
+
/// Creates a UUID from the data pointed to by the bytes argument. No special
/// significance is attached to any of the values.
static UUID fromData(const void *bytes, uint32_t num_bytes) {
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/UnimplementedError.h b/contrib/llvm-project/lldb/include/lldb/Utility/UnimplementedError.h
new file mode 100644
index 000000000000..c6fab0a9483c
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/UnimplementedError.h
@@ -0,0 +1,28 @@
+//===-- UnimplementedError.h ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_UTILITY_UNIMPLEMENTEDERROR_H
+#define LLDB_UTILITY_UNIMPLEMENTEDERROR_H
+
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
+
+namespace lldb_private {
+class UnimplementedError : public llvm::ErrorInfo<UnimplementedError> {
+public:
+ static char ID;
+
+ void log(llvm::raw_ostream &OS) const override { OS << "Not implemented"; }
+
+ std::error_code convertToErrorCode() const override {
+ return llvm::errc::not_supported;
+ };
+};
+} // namespace lldb_private
+
+#endif // LLDB_UTILITY_UNIMPLEMENTEDERROR_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/XcodeSDK.h b/contrib/llvm-project/lldb/include/lldb/Utility/XcodeSDK.h
index 307fe7f46798..878b131a1814 100644
--- a/contrib/llvm-project/lldb/include/lldb/Utility/XcodeSDK.h
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/XcodeSDK.h
@@ -65,11 +65,11 @@ public:
/// The merge function follows a strict order to maintain monotonicity:
/// 1. SDK with the higher SDKType wins.
/// 2. The newer SDK wins.
- void Merge(XcodeSDK other);
+ void Merge(const XcodeSDK &other);
- XcodeSDK &operator=(XcodeSDK other);
+ XcodeSDK &operator=(const XcodeSDK &other);
XcodeSDK(const XcodeSDK&) = default;
- bool operator==(XcodeSDK other);
+ bool operator==(const XcodeSDK &other);
/// Return parsed SDK type and version number.
Info Parse() const;
diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-defines.h b/contrib/llvm-project/lldb/include/lldb/lldb-defines.h
index fea8079779a1..487cd0b01d5c 100644
--- a/contrib/llvm-project/lldb/include/lldb/lldb-defines.h
+++ b/contrib/llvm-project/lldb/include/lldb/lldb-defines.h
@@ -95,6 +95,7 @@
#define LLDB_INVALID_SIGNAL_NUMBER INT32_MAX
#define LLDB_INVALID_OFFSET UINT64_MAX // Must match max of lldb::offset_t
#define LLDB_INVALID_LINE_NUMBER UINT32_MAX
+#define LLDB_INVALID_COLUMN_NUMBER 0
#define LLDB_INVALID_QUEUE_ID 0
/// CPU Type definitions
@@ -119,6 +120,7 @@
#define LLDB_OPT_SET_9 (1U << 8)
#define LLDB_OPT_SET_10 (1U << 9)
#define LLDB_OPT_SET_11 (1U << 10)
+#define LLDB_OPT_SET_12 (1U << 11)
#define LLDB_OPT_SET_FROM_TO(A, B) \
(((1U << (B)) - 1) ^ (((1U << (A)) - 1) >> 1))
diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h b/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h
index c9def56ff109..b3f8198b1146 100644
--- a/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h
+++ b/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h
@@ -126,6 +126,9 @@ FLAGS_ENUM(LaunchFlags){
eLaunchFlagShellExpandArguments =
(1u << 10), ///< Perform shell-style argument expansion
eLaunchFlagCloseTTYOnExit = (1u << 11), ///< Close the open TTY on exit
+ eLaunchFlagInheritTCCFromParent =
+ (1u << 12), ///< Don't make the inferior responsible for its own TCC
+ ///< permissions but instead inherit them from its parent.
};
/// Thread Run Modes.
@@ -526,6 +529,7 @@ enum CommandArgumentType {
eArgTypeExpression,
eArgTypeExpressionPath,
eArgTypeExprFormat,
+ eArgTypeFileLineColumn,
eArgTypeFilename,
eArgTypeFormat,
eArgTypeFrameIndex,
@@ -592,6 +596,7 @@ enum CommandArgumentType {
eArgRawInput,
eArgTypeCommand,
eArgTypeColumnNum,
+ eArgTypeModuleUUID,
eArgTypeLastArg // Always keep this entry as the last entry in this
// enumeration!!
};
@@ -764,10 +769,11 @@ enum BasicType {
eBasicTypeOther
};
+/// Deprecated
enum TraceType {
eTraceTypeNone = 0,
- // Hardware Trace generated by the processor.
+ /// Intel Processor Trace
eTraceTypeProcessorTrace
};
@@ -964,7 +970,7 @@ enum GdbSignal {
eGdbSignalBreakpoint = 0x96
};
-/// Used with SBHost::GetPath (lldb::PathType) to find files that are
+/// Used with SBHostOS::GetLLDBPath (lldb::PathType) to find files that are
/// related to LLDB on the current host machine. Most files are
/// relative to LLDB or are in known locations.
enum PathType {
@@ -1075,7 +1081,12 @@ FLAGS_ENUM(CommandFlags){
///
/// Verifies that there is a paused process in m_exe_ctx, if there isn't,
/// the command will fail with an appropriate error message.
- eCommandProcessMustBePaused = (1u << 7)};
+ eCommandProcessMustBePaused = (1u << 7),
+ /// eCommandProcessMustBeTraced
+ ///
+ /// Verifies that the process is being traced by a Trace plug-in, if it
+ /// isn't the command will fail with an appropriate error message.
+ eCommandProcessMustBeTraced = (1u << 8)};
/// Whether a summary should cap how much data it returns to users or not.
enum TypeSummaryCapping {
diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-forward.h b/contrib/llvm-project/lldb/include/lldb/lldb-forward.h
index 4fd2a07dd616..a297a928a3f4 100644
--- a/contrib/llvm-project/lldb/include/lldb/lldb-forward.h
+++ b/contrib/llvm-project/lldb/include/lldb/lldb-forward.h
@@ -192,7 +192,6 @@ class Status;
class StopInfo;
class Stoppoint;
class StoppointCallbackContext;
-class StoppointLocation;
class Stream;
class StreamFile;
class StreamString;
@@ -227,6 +226,9 @@ class ThreadPlanStepRange;
class ThreadPlanStepThrough;
class ThreadPlanTracer;
class ThreadSpec;
+class ThreadTrace;
+class Trace;
+class TraceSessionFileParser;
class TraceOptions;
class Type;
class TypeAndOrName;
@@ -402,8 +404,9 @@ typedef std::weak_ptr<lldb_private::StackFrame> StackFrameWP;
typedef std::shared_ptr<lldb_private::StackFrameList> StackFrameListSP;
typedef std::shared_ptr<lldb_private::StackFrameRecognizer>
StackFrameRecognizerSP;
+typedef std::unique_ptr<lldb_private::StackFrameRecognizerManager>
+ StackFrameRecognizerManagerUP;
typedef std::shared_ptr<lldb_private::StopInfo> StopInfoSP;
-typedef std::shared_ptr<lldb_private::StoppointLocation> StoppointLocationSP;
typedef std::shared_ptr<lldb_private::Stream> StreamSP;
typedef std::weak_ptr<lldb_private::Stream> StreamWP;
typedef std::shared_ptr<lldb_private::StreamFile> StreamFileSP;
@@ -430,7 +433,9 @@ typedef std::shared_ptr<lldb_private::Thread> ThreadSP;
typedef std::weak_ptr<lldb_private::Thread> ThreadWP;
typedef std::shared_ptr<lldb_private::ThreadCollection> ThreadCollectionSP;
typedef std::shared_ptr<lldb_private::ThreadPlan> ThreadPlanSP;
+typedef std::weak_ptr<lldb_private::ThreadPlan> ThreadPlanWP;
typedef std::shared_ptr<lldb_private::ThreadPlanTracer> ThreadPlanTracerSP;
+typedef std::shared_ptr<lldb_private::Trace> TraceSP;
typedef std::shared_ptr<lldb_private::TraceOptions> TraceOptionsSP;
typedef std::shared_ptr<lldb_private::Type> TypeSP;
typedef std::weak_ptr<lldb_private::Type> TypeWP;
diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-private-interfaces.h b/contrib/llvm-project/lldb/include/lldb/lldb-private-interfaces.h
index 1568e7a3cb51..df33f8af0e14 100644
--- a/contrib/llvm-project/lldb/include/lldb/lldb-private-interfaces.h
+++ b/contrib/llvm-project/lldb/include/lldb/lldb-private-interfaces.h
@@ -18,6 +18,13 @@
#include <memory>
#include <set>
+namespace llvm {
+namespace json {
+class Object;
+class Value;
+}
+} // namespace llvm
+
namespace lldb_private {
typedef lldb::ABISP (*ABICreateInstance)(lldb::ProcessSP process_sp,
const ArchSpec &arch);
@@ -69,7 +76,7 @@ typedef lldb::PlatformSP (*PlatformCreateInstance)(bool force,
const ArchSpec *arch);
typedef lldb::ProcessSP (*ProcessCreateInstance)(
lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
- const FileSpec *crash_file_path);
+ const FileSpec *crash_file_path, bool can_connect);
typedef lldb::ScriptInterpreterSP (*ScriptInterpreterCreateInstance)(
Debugger &debugger);
typedef SymbolFile *(*SymbolFileCreateInstance)(lldb::ObjectFileSP objfile_sp);
@@ -104,6 +111,11 @@ typedef lldb::REPLSP (*REPLCreateInstance)(Status &error,
const char *repl_options);
typedef int (*ComparisonFunction)(const void *, const void *);
typedef void (*DebuggerInitializeCallback)(Debugger &debugger);
+typedef llvm::Expected<lldb::TraceSP> (*TraceCreateInstance)(
+ const llvm::json::Value &trace_session_file,
+ llvm::StringRef session_file_dir, lldb_private::Debugger &debugger);
+typedef lldb::CommandObjectSP (*TraceGetStartCommand)(
+ CommandInterpreter &interpreter);
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-private-types.h b/contrib/llvm-project/lldb/include/lldb/lldb-private-types.h
index fb8c2db2e21c..c7e652650da7 100644
--- a/contrib/llvm-project/lldb/include/lldb/lldb-private-types.h
+++ b/contrib/llvm-project/lldb/include/lldb/lldb-private-types.h
@@ -107,33 +107,6 @@ struct OptionValidator {
virtual const char *LongConditionString() const = 0;
};
-struct OptionDefinition {
- /// Used to mark options that can be used together. If
- /// `(1 << n & usage_mask) != 0` then this option belongs to option set n.
- uint32_t usage_mask;
- /// This option is required (in the current usage level).
- bool required;
- /// Full name for this option.
- const char *long_option;
- /// Single character for this option.
- int short_option;
- /// no_argument, required_argument or optional_argument
- int option_has_arg;
- /// If non-NULL, option is valid iff |validator->IsValid()|, otherwise
- /// always valid.
- OptionValidator *validator;
- /// If not empty, an array of enum values.
- OptionEnumValues enum_values;
- /// The kind of completion for this option.
- /// Contains values of the CommandCompletions::CommonCompletionTypes enum.
- uint32_t completion_type;
- /// Type of argument this option takes.
- lldb::CommandArgumentType argument_type;
- /// Full text explaining what this options does and what (if any) argument to
- /// pass it.
- const char *usage_text;
-};
-
typedef struct type128 { uint64_t x[2]; } type128;
typedef struct type256 { uint64_t x[4]; } type256;
diff --git a/contrib/llvm-project/lldb/source/API/SBAddress.cpp b/contrib/llvm-project/lldb/source/API/SBAddress.cpp
index 6444a006c0ff..7c102270a87c 100644
--- a/contrib/llvm-project/lldb/source/API/SBAddress.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBAddress.cpp
@@ -25,11 +25,8 @@ SBAddress::SBAddress() : m_opaque_up(new Address()) {
LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBAddress);
}
-SBAddress::SBAddress(const Address *lldb_object_ptr)
- : m_opaque_up(new Address()) {
- if (lldb_object_ptr)
- m_opaque_up = std::make_unique<Address>(*lldb_object_ptr);
-}
+SBAddress::SBAddress(const Address &address)
+ : m_opaque_up(std::make_unique<Address>(address)) {}
SBAddress::SBAddress(const SBAddress &rhs) : m_opaque_up(new Address()) {
LLDB_RECORD_CONSTRUCTOR(SBAddress, (const lldb::SBAddress &), rhs);
@@ -101,12 +98,7 @@ void SBAddress::SetAddress(lldb::SBSection section, lldb::addr_t offset) {
addr.SetOffset(offset);
}
-void SBAddress::SetAddress(const Address *lldb_object_ptr) {
- if (lldb_object_ptr)
- ref() = *lldb_object_ptr;
- else
- m_opaque_up = std::make_unique<Address>();
-}
+void SBAddress::SetAddress(const Address &address) { ref() = address; }
lldb::addr_t SBAddress::GetFileAddress() const {
LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::addr_t, SBAddress, GetFileAddress);
diff --git a/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp b/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp
index eb75bf8b33f4..96ae305ffce5 100644
--- a/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp
@@ -81,6 +81,16 @@ bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) {
return m_opaque_wp.lock() != rhs.m_opaque_wp.lock();
}
+SBTarget SBBreakpoint::GetTarget() const {
+ LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBTarget, SBBreakpoint, GetTarget);
+
+ BreakpointSP bkpt_sp = GetSP();
+ if (bkpt_sp)
+ return LLDB_RECORD_RESULT(SBTarget(bkpt_sp->GetTargetSP()));
+
+ return LLDB_RECORD_RESULT(SBTarget());
+}
+
break_id_t SBBreakpoint::GetID() const {
LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::break_id_t, SBBreakpoint, GetID);
@@ -575,7 +585,22 @@ SBError SBBreakpoint::AddLocation(SBAddress &address) {
return LLDB_RECORD_RESULT(error);
}
-void SBBreakpoint ::SetCallback(SBBreakpointHitCallback callback, void *baton) {
+SBStructuredData SBBreakpoint::SerializeToStructuredData() {
+ LLDB_RECORD_METHOD_NO_ARGS(lldb::SBStructuredData, SBBreakpoint,
+ SerializeToStructuredData);
+
+ SBStructuredData data;
+ BreakpointSP bkpt_sp = GetSP();
+
+ if (!bkpt_sp)
+ return LLDB_RECORD_RESULT(data);
+
+ StructuredData::ObjectSP bkpt_dict = bkpt_sp->SerializeToStructuredData();
+ data.m_impl_up->SetObjectSP(bkpt_dict);
+ return LLDB_RECORD_RESULT(data);
+}
+
+void SBBreakpoint::SetCallback(SBBreakpointHitCallback callback, void *baton) {
LLDB_RECORD_DUMMY(void, SBBreakpoint, SetCallback,
(lldb::SBBreakpointHitCallback, void *), callback, baton);
@@ -972,6 +997,7 @@ void RegisterMethods<SBBreakpoint>(Registry &R) {
SBBreakpoint, operator==,(const lldb::SBBreakpoint &));
LLDB_REGISTER_METHOD(bool,
SBBreakpoint, operator!=,(const lldb::SBBreakpoint &));
+ LLDB_REGISTER_METHOD_CONST(lldb::SBTarget, SBBreakpoint, GetTarget, ());
LLDB_REGISTER_METHOD_CONST(lldb::break_id_t, SBBreakpoint, GetID, ());
LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsValid, ());
LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, operator bool, ());
@@ -1017,6 +1043,8 @@ void RegisterMethods<SBBreakpoint>(Registry &R) {
(lldb::SBStream &, bool));
LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, AddLocation,
(lldb::SBAddress &));
+ LLDB_REGISTER_METHOD(lldb::SBStructuredData, SBBreakpoint,
+ SerializeToStructuredData, ());
LLDB_REGISTER_METHOD(void, SBBreakpoint, SetScriptCallbackFunction,
(const char *));
LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, SetScriptCallbackFunction,
diff --git a/contrib/llvm-project/lldb/source/API/SBBreakpointLocation.cpp b/contrib/llvm-project/lldb/source/API/SBBreakpointLocation.cpp
index e29f3fd9c50e..d6bbb5faf041 100644
--- a/contrib/llvm-project/lldb/source/API/SBBreakpointLocation.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBBreakpointLocation.cpp
@@ -80,7 +80,7 @@ SBAddress SBBreakpointLocation::GetAddress() {
BreakpointLocationSP loc_sp = GetSP();
if (loc_sp) {
- return LLDB_RECORD_RESULT(SBAddress(&loc_sp->GetAddress()));
+ return LLDB_RECORD_RESULT(SBAddress(loc_sp->GetAddress()));
}
return LLDB_RECORD_RESULT(SBAddress());
@@ -218,8 +218,8 @@ SBError SBBreakpointLocation::SetScriptCallbackFunction(
const char *callback_function_name,
SBStructuredData &extra_args) {
LLDB_RECORD_METHOD(SBError, SBBreakpointLocation, SetScriptCallbackFunction,
- (const char *, SBStructuredData &),
- callback_function_name, extra_args);
+ (const char *, SBStructuredData &), callback_function_name,
+ extra_args);
SBError sb_error;
BreakpointLocationSP loc_sp = GetSP();
@@ -239,7 +239,7 @@ SBError SBBreakpointLocation::SetScriptCallbackFunction(
sb_error.SetError(error);
} else
sb_error.SetErrorString("invalid breakpoint");
-
+
return LLDB_RECORD_RESULT(sb_error);
}
diff --git a/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp b/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp
index f4f19577b36c..31e7da8323b8 100644
--- a/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp
@@ -478,6 +478,24 @@ void SBCommandInterpreter::SourceInitFileInHomeDirectory(
}
}
+void SBCommandInterpreter::SourceInitFileInHomeDirectory(
+ SBCommandReturnObject &result, bool is_repl) {
+ LLDB_RECORD_METHOD(void, SBCommandInterpreter, SourceInitFileInHomeDirectory,
+ (lldb::SBCommandReturnObject &, bool), result, is_repl);
+
+ result.Clear();
+ if (IsValid()) {
+ TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
+ std::unique_lock<std::recursive_mutex> lock;
+ if (target_sp)
+ lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
+ m_opaque_ptr->SourceInitFileHome(result.ref(), is_repl);
+ } else {
+ result->AppendError("SBCommandInterpreter is not valid");
+ result->SetStatus(eReturnStatusFailed);
+ }
+}
+
void SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory(
SBCommandReturnObject &result) {
LLDB_RECORD_METHOD(void, SBCommandInterpreter,
@@ -807,6 +825,9 @@ template <> void RegisterMethods<SBCommandInterpreter>(Registry &R) {
SourceInitFileInHomeDirectory,
(lldb::SBCommandReturnObject &));
LLDB_REGISTER_METHOD(void, SBCommandInterpreter,
+ SourceInitFileInHomeDirectory,
+ (lldb::SBCommandReturnObject &, bool));
+ LLDB_REGISTER_METHOD(void, SBCommandInterpreter,
SourceInitFileInCurrentWorkingDirectory,
(lldb::SBCommandReturnObject &));
LLDB_REGISTER_METHOD(lldb::SBBroadcaster, SBCommandInterpreter,
diff --git a/contrib/llvm-project/lldb/source/API/SBCommandInterpreterRunOptions.cpp b/contrib/llvm-project/lldb/source/API/SBCommandInterpreterRunOptions.cpp
index fcfbf5e5401a..da800e8b7804 100644
--- a/contrib/llvm-project/lldb/source/API/SBCommandInterpreterRunOptions.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBCommandInterpreterRunOptions.cpp
@@ -24,8 +24,29 @@ SBCommandInterpreterRunOptions::SBCommandInterpreterRunOptions() {
m_opaque_up = std::make_unique<CommandInterpreterRunOptions>();
}
+SBCommandInterpreterRunOptions::SBCommandInterpreterRunOptions(
+ const SBCommandInterpreterRunOptions &rhs)
+ : m_opaque_up() {
+ LLDB_RECORD_CONSTRUCTOR(SBCommandInterpreterRunOptions,
+ (const lldb::SBCommandInterpreterRunOptions &), rhs);
+
+ m_opaque_up = std::make_unique<CommandInterpreterRunOptions>(rhs.ref());
+}
+
SBCommandInterpreterRunOptions::~SBCommandInterpreterRunOptions() = default;
+SBCommandInterpreterRunOptions &SBCommandInterpreterRunOptions::operator=(
+ const SBCommandInterpreterRunOptions &rhs) {
+ LLDB_RECORD_METHOD(lldb::SBCommandInterpreterRunOptions &,
+ SBCommandInterpreterRunOptions, operator=,
+ (const lldb::SBCommandInterpreterRunOptions &), rhs);
+
+ if (this == &rhs)
+ return LLDB_RECORD_RESULT(*this);
+ *m_opaque_up = *rhs.m_opaque_up;
+ return LLDB_RECORD_RESULT(*this);
+}
+
bool SBCommandInterpreterRunOptions::GetStopOnContinue() const {
LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreterRunOptions,
GetStopOnContinue);
@@ -190,12 +211,11 @@ SBCommandInterpreterRunResult::~SBCommandInterpreterRunResult() = default;
SBCommandInterpreterRunResult &SBCommandInterpreterRunResult::operator=(
const SBCommandInterpreterRunResult &rhs) {
LLDB_RECORD_METHOD(lldb::SBCommandInterpreterRunResult &,
- SBCommandInterpreterRunResult,
- operator=,(const lldb::SBCommandInterpreterRunResult &),
- rhs);
+ SBCommandInterpreterRunResult, operator=,
+ (const lldb::SBCommandInterpreterRunResult &), rhs);
if (this == &rhs)
- return *this;
+ return LLDB_RECORD_RESULT(*this);
*m_opaque_up = *rhs.m_opaque_up;
return LLDB_RECORD_RESULT(*this);
}
@@ -220,6 +240,11 @@ namespace repro {
template <> void RegisterMethods<SBCommandInterpreterRunOptions>(Registry &R) {
LLDB_REGISTER_CONSTRUCTOR(SBCommandInterpreterRunOptions, ());
+ LLDB_REGISTER_CONSTRUCTOR(SBCommandInterpreterRunOptions,
+ (const lldb::SBCommandInterpreterRunOptions &));
+ LLDB_REGISTER_METHOD(lldb::SBCommandInterpreterRunOptions &,
+ SBCommandInterpreterRunOptions, operator=,
+ (const lldb::SBCommandInterpreterRunOptions &));
LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreterRunOptions,
GetStopOnContinue, ());
LLDB_REGISTER_METHOD(void, SBCommandInterpreterRunOptions, SetStopOnContinue,
@@ -260,8 +285,8 @@ template <> void RegisterMethods<SBCommandInterpreterRunOptions>(Registry &R) {
LLDB_REGISTER_CONSTRUCTOR(SBCommandInterpreterRunResult,
(const lldb::SBCommandInterpreterRunResult &));
LLDB_REGISTER_METHOD(lldb::SBCommandInterpreterRunResult &,
- SBCommandInterpreterRunResult,
- operator=,(const lldb::SBCommandInterpreterRunResult &));
+ SBCommandInterpreterRunResult, operator=,
+ (const lldb::SBCommandInterpreterRunResult &));
LLDB_REGISTER_METHOD_CONST(int, SBCommandInterpreterRunResult,
GetNumberOfErrors, ());
LLDB_REGISTER_METHOD_CONST(lldb::CommandInterpreterResult,
diff --git a/contrib/llvm-project/lldb/source/API/SBDebugger.cpp b/contrib/llvm-project/lldb/source/API/SBDebugger.cpp
index 5f62987f37da..6245b3a83565 100644
--- a/contrib/llvm-project/lldb/source/API/SBDebugger.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBDebugger.cpp
@@ -220,7 +220,7 @@ SBDebugger SBDebugger::Create(bool source_init_files,
interp.get()->SkipLLDBInitFiles(false);
interp.get()->SkipAppInitFiles(false);
SBCommandReturnObject result;
- interp.SourceInitFileInHomeDirectory(result);
+ interp.SourceInitFileInHomeDirectory(result, false);
} else {
interp.get()->SkipLLDBInitFiles(true);
interp.get()->SkipAppInitFiles(true);
@@ -804,23 +804,33 @@ SBTarget SBDebugger::CreateTargetWithFileAndArch(const char *filename,
TargetSP target_sp;
if (m_opaque_sp) {
Status error;
- const bool add_dependent_modules = true;
-
- error = m_opaque_sp->GetTargetList().CreateTarget(
- *m_opaque_sp, filename, arch_cstr,
- add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr,
- target_sp);
-
- if (error.Success()) {
- m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get());
- sb_target.SetSP(target_sp);
+ if (arch_cstr == nullptr) {
+ // The version of CreateTarget that takes an ArchSpec won't accept an
+ // empty ArchSpec, so when the arch hasn't been specified, we need to
+ // call the target triple version.
+ error = m_opaque_sp->GetTargetList().CreateTarget(*m_opaque_sp, filename,
+ arch_cstr, eLoadDependentsYes, nullptr, target_sp);
+ } else {
+ PlatformSP platform_sp = m_opaque_sp->GetPlatformList()
+ .GetSelectedPlatform();
+ ArchSpec arch = Platform::GetAugmentedArchSpec(platform_sp.get(),
+ arch_cstr);
+ if (arch.IsValid())
+ error = m_opaque_sp->GetTargetList().CreateTarget(*m_opaque_sp, filename,
+ arch, eLoadDependentsYes, platform_sp, target_sp);
+ else
+ error.SetErrorStringWithFormat("invalid arch_cstr: %s", arch_cstr);
}
+ if (error.Success())
+ sb_target.SetSP(target_sp);
}
-
+
LLDB_LOGF(log,
"SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", "
"arch=%s) => SBTarget(%p)",
- static_cast<void *>(m_opaque_sp.get()), filename, arch_cstr,
+ static_cast<void *>(m_opaque_sp.get()),
+ filename ? filename : "<unspecified>",
+ arch_cstr ? arch_cstr : "<unspecified>",
static_cast<void *>(target_sp.get()));
return LLDB_RECORD_RESULT(sb_target);
@@ -840,10 +850,8 @@ SBTarget SBDebugger::CreateTarget(const char *filename) {
add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr,
target_sp);
- if (error.Success()) {
- m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get());
+ if (error.Success())
sb_target.SetSP(target_sp);
- }
}
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
LLDB_LOGF(log,
@@ -858,7 +866,7 @@ SBTarget SBDebugger::GetDummyTarget() {
SBTarget sb_target;
if (m_opaque_sp) {
- sb_target.SetSP(m_opaque_sp->GetDummyTarget()->shared_from_this());
+ sb_target.SetSP(m_opaque_sp->GetDummyTarget().shared_from_this());
}
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
LLDB_LOGF(log, "SBDebugger(%p)::GetDummyTarget() => SBTarget(%p)",
@@ -879,8 +887,6 @@ bool SBDebugger::DeleteTarget(lldb::SBTarget &target) {
result = m_opaque_sp->GetTargetList().DeleteTarget(target_sp);
target_sp->Destroy();
target.Clear();
- const bool mandatory = true;
- ModuleList::RemoveOrphanSharedModules(mandatory);
}
}
@@ -1000,7 +1006,7 @@ void SBDebugger::SetSelectedTarget(SBTarget &sb_target) {
TargetSP target_sp(sb_target.GetSP());
if (m_opaque_sp) {
- m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get());
+ m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp);
}
if (log) {
SBStream sstr;
diff --git a/contrib/llvm-project/lldb/source/API/SBError.cpp b/contrib/llvm-project/lldb/source/API/SBError.cpp
index 67c7663d3583..f979572778e0 100644
--- a/contrib/llvm-project/lldb/source/API/SBError.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBError.cpp
@@ -118,7 +118,7 @@ void SBError::SetErrorToGenericError() {
LLDB_RECORD_METHOD_NO_ARGS(void, SBError, SetErrorToGenericError);
CreateIfNeeded();
- m_opaque_up->SetErrorToErrno();
+ m_opaque_up->SetErrorToGenericError();
}
void SBError::SetErrorString(const char *err_str) {
diff --git a/contrib/llvm-project/lldb/source/API/SBFrame.cpp b/contrib/llvm-project/lldb/source/API/SBFrame.cpp
index 81782dbf838f..8f9e426e066e 100644
--- a/contrib/llvm-project/lldb/source/API/SBFrame.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBFrame.cpp
@@ -431,7 +431,7 @@ SBAddress SBFrame::GetPCAddress() const {
if (stop_locker.TryLock(&process->GetRunLock())) {
frame = exe_ctx.GetFramePtr();
if (frame)
- sb_addr.SetAddress(&frame->GetFrameCodeAddress());
+ sb_addr.SetAddress(frame->GetFrameCodeAddress());
}
}
return LLDB_RECORD_RESULT(sb_addr);
diff --git a/contrib/llvm-project/lldb/source/API/SBFunction.cpp b/contrib/llvm-project/lldb/source/API/SBFunction.cpp
index e49513bd0da5..9f3cf817fc8c 100644
--- a/contrib/llvm-project/lldb/source/API/SBFunction.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBFunction.cpp
@@ -152,7 +152,7 @@ SBAddress SBFunction::GetStartAddress() {
SBAddress addr;
if (m_opaque_ptr)
- addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress());
+ addr.SetAddress(m_opaque_ptr->GetAddressRange().GetBaseAddress());
return LLDB_RECORD_RESULT(addr);
}
@@ -163,7 +163,7 @@ SBAddress SBFunction::GetEndAddress() {
if (m_opaque_ptr) {
addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize();
if (byte_size > 0) {
- addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress());
+ addr.SetAddress(m_opaque_ptr->GetAddressRange().GetBaseAddress());
addr->Slide(byte_size);
}
}
diff --git a/contrib/llvm-project/lldb/source/API/SBHostOS.cpp b/contrib/llvm-project/lldb/source/API/SBHostOS.cpp
index 9d3d119e4c2a..deca4ac81a1a 100644
--- a/contrib/llvm-project/lldb/source/API/SBHostOS.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBHostOS.cpp
@@ -91,14 +91,13 @@ SBFileSpec SBHostOS::GetUserHomeDirectory() {
LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::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());
+ FileSpec homedir;
+ FileSystem::Instance().GetHomeDirectory(homedir);
FileSystem::Instance().Resolve(homedir);
+ SBFileSpec sb_fspec;
sb_fspec.SetFileSpec(homedir);
+
return LLDB_RECORD_RESULT(sb_fspec);
}
diff --git a/contrib/llvm-project/lldb/source/API/SBInstruction.cpp b/contrib/llvm-project/lldb/source/API/SBInstruction.cpp
index 207e81272e50..579ddf84cf45 100644
--- a/contrib/llvm-project/lldb/source/API/SBInstruction.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBInstruction.cpp
@@ -107,7 +107,7 @@ SBAddress SBInstruction::GetAddress() {
SBAddress sb_addr;
lldb::InstructionSP inst_sp(GetOpaque());
if (inst_sp && inst_sp->GetAddress().IsValid())
- sb_addr.SetAddress(&inst_sp->GetAddress());
+ sb_addr.SetAddress(inst_sp->GetAddress());
return LLDB_RECORD_RESULT(sb_addr);
}
diff --git a/contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp b/contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp
index ba13072e8f9b..cda8134c9853 100644
--- a/contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp
@@ -190,9 +190,10 @@ void SBLaunchInfo::SetEnvironment(const SBEnvironment &env, bool append) {
LLDB_RECORD_METHOD(void, SBLaunchInfo, SetEnvironment,
(const lldb::SBEnvironment &, bool), env, append);
Environment &refEnv = env.ref();
- if (append)
- m_opaque_sp->GetEnvironment().insert(refEnv.begin(), refEnv.end());
- else
+ if (append) {
+ for (auto &KV : refEnv)
+ m_opaque_sp->GetEnvironment().insert_or_assign(KV.first(), KV.second);
+ } else
m_opaque_sp->GetEnvironment() = refEnv;
m_opaque_sp->RegenerateEnvp();
}
diff --git a/contrib/llvm-project/lldb/source/API/SBLineEntry.cpp b/contrib/llvm-project/lldb/source/API/SBLineEntry.cpp
index cefbe3ee1a1e..9866acbcbec3 100644
--- a/contrib/llvm-project/lldb/source/API/SBLineEntry.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBLineEntry.cpp
@@ -56,7 +56,7 @@ SBAddress SBLineEntry::GetStartAddress() const {
SBAddress sb_address;
if (m_opaque_up)
- sb_address.SetAddress(&m_opaque_up->range.GetBaseAddress());
+ sb_address.SetAddress(m_opaque_up->range.GetBaseAddress());
return LLDB_RECORD_RESULT(sb_address);
}
@@ -66,7 +66,7 @@ SBAddress SBLineEntry::GetEndAddress() const {
SBAddress sb_address;
if (m_opaque_up) {
- sb_address.SetAddress(&m_opaque_up->range.GetBaseAddress());
+ sb_address.SetAddress(m_opaque_up->range.GetBaseAddress());
sb_address.OffsetAddress(m_opaque_up->range.GetByteSize());
}
return LLDB_RECORD_RESULT(sb_address);
diff --git a/contrib/llvm-project/lldb/source/API/SBModule.cpp b/contrib/llvm-project/lldb/source/API/SBModule.cpp
index c30529b37eb1..b5b9fe16aa63 100644
--- a/contrib/llvm-project/lldb/source/API/SBModule.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBModule.cpp
@@ -67,8 +67,8 @@ SBModule::SBModule(lldb::SBProcess &process, lldb::addr_t header_addr)
}
const SBModule &SBModule::operator=(const SBModule &rhs) {
- LLDB_RECORD_METHOD(const lldb::SBModule &,
- SBModule, operator=,(const lldb::SBModule &), rhs);
+ LLDB_RECORD_METHOD(const lldb::SBModule &, SBModule, operator=,
+ (const lldb::SBModule &), rhs);
if (this != &rhs)
m_opaque_sp = rhs.m_opaque_sp;
@@ -108,7 +108,6 @@ lldb::SBFileSpec SBModule::GetPlatformFileSpec() const {
LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBFileSpec, SBModule,
GetPlatformFileSpec);
-
SBFileSpec file_spec;
ModuleSP module_sp(GetSP());
if (module_sp)
@@ -187,7 +186,7 @@ const char *SBModule::GetUUIDString() const {
}
bool SBModule::operator==(const SBModule &rhs) const {
- LLDB_RECORD_METHOD_CONST(bool, SBModule, operator==,(const lldb::SBModule &),
+ LLDB_RECORD_METHOD_CONST(bool, SBModule, operator==, (const lldb::SBModule &),
rhs);
if (m_opaque_sp)
@@ -196,7 +195,7 @@ bool SBModule::operator==(const SBModule &rhs) const {
}
bool SBModule::operator!=(const SBModule &rhs) const {
- LLDB_RECORD_METHOD_CONST(bool, SBModule, operator!=,(const lldb::SBModule &),
+ LLDB_RECORD_METHOD_CONST(bool, SBModule, operator!=, (const lldb::SBModule &),
rhs);
if (m_opaque_sp)
@@ -625,7 +624,7 @@ uint32_t SBModule::GetVersion(uint32_t *versions, uint32_t num_versions) {
++result;
if (version.getMinor())
++result;
- if(version.getSubminor())
+ if (version.getSubminor())
++result;
if (!versions)
@@ -690,17 +689,24 @@ uint32_t SBModule::GetNumberAllocatedModules() {
return Module::GetNumberAllocatedModules();
}
+void SBModule::GarbageCollectAllocatedModules() {
+ LLDB_RECORD_STATIC_METHOD_NO_ARGS(void, SBModule,
+ GarbageCollectAllocatedModules);
+
+ const bool mandatory = false;
+ ModuleList::RemoveOrphanSharedModules(mandatory);
+}
+
namespace lldb_private {
namespace repro {
-template <>
-void RegisterMethods<SBModule>(Registry &R) {
+template <> void RegisterMethods<SBModule>(Registry &R) {
LLDB_REGISTER_CONSTRUCTOR(SBModule, ());
LLDB_REGISTER_CONSTRUCTOR(SBModule, (const lldb::SBModuleSpec &));
LLDB_REGISTER_CONSTRUCTOR(SBModule, (const lldb::SBModule &));
LLDB_REGISTER_CONSTRUCTOR(SBModule, (lldb::SBProcess &, lldb::addr_t));
- LLDB_REGISTER_METHOD(const lldb::SBModule &,
- SBModule, operator=,(const lldb::SBModule &));
+ LLDB_REGISTER_METHOD(const lldb::SBModule &, SBModule, operator=,
+ (const lldb::SBModule &));
LLDB_REGISTER_METHOD_CONST(bool, SBModule, IsValid, ());
LLDB_REGISTER_METHOD_CONST(bool, SBModule, operator bool, ());
LLDB_REGISTER_METHOD(void, SBModule, Clear, ());
@@ -714,10 +720,10 @@ void RegisterMethods<SBModule>(Registry &R) {
LLDB_REGISTER_METHOD(bool, SBModule, SetRemoteInstallFileSpec,
(lldb::SBFileSpec &));
LLDB_REGISTER_METHOD_CONST(const char *, SBModule, GetUUIDString, ());
- LLDB_REGISTER_METHOD_CONST(bool,
- SBModule, operator==,(const lldb::SBModule &));
- LLDB_REGISTER_METHOD_CONST(bool,
- SBModule, operator!=,(const lldb::SBModule &));
+ LLDB_REGISTER_METHOD_CONST(bool, SBModule, operator==,
+ (const lldb::SBModule &));
+ LLDB_REGISTER_METHOD_CONST(bool, SBModule, operator!=,
+ (const lldb::SBModule &));
LLDB_REGISTER_METHOD(lldb::SBAddress, SBModule, ResolveFileAddress,
(lldb::addr_t));
LLDB_REGISTER_METHOD(lldb::SBSymbolContext, SBModule,
@@ -736,8 +742,7 @@ void RegisterMethods<SBModule>(Registry &R) {
LLDB_REGISTER_METHOD(lldb::SBSymbolContextList, SBModule, FindSymbols,
(const char *, lldb::SymbolType));
LLDB_REGISTER_METHOD(size_t, SBModule, GetNumSections, ());
- LLDB_REGISTER_METHOD(lldb::SBSection, SBModule, GetSectionAtIndex,
- (size_t));
+ LLDB_REGISTER_METHOD(lldb::SBSection, SBModule, GetSectionAtIndex, (size_t));
LLDB_REGISTER_METHOD(lldb::SBSymbolContextList, SBModule, FindFunctions,
(const char *, uint32_t));
LLDB_REGISTER_METHOD(lldb::SBValueList, SBModule, FindGlobalVariables,
@@ -745,28 +750,25 @@ void RegisterMethods<SBModule>(Registry &R) {
LLDB_REGISTER_METHOD(lldb::SBValue, SBModule, FindFirstGlobalVariable,
(lldb::SBTarget &, const char *));
LLDB_REGISTER_METHOD(lldb::SBType, SBModule, FindFirstType, (const char *));
- LLDB_REGISTER_METHOD(lldb::SBType, SBModule, GetBasicType,
- (lldb::BasicType));
+ LLDB_REGISTER_METHOD(lldb::SBType, SBModule, GetBasicType, (lldb::BasicType));
LLDB_REGISTER_METHOD(lldb::SBTypeList, SBModule, FindTypes, (const char *));
- LLDB_REGISTER_METHOD(lldb::SBType, SBModule, GetTypeByID,
- (lldb::user_id_t));
+ LLDB_REGISTER_METHOD(lldb::SBType, SBModule, GetTypeByID, (lldb::user_id_t));
LLDB_REGISTER_METHOD(lldb::SBTypeList, SBModule, GetTypes, (uint32_t));
- LLDB_REGISTER_METHOD(lldb::SBSection, SBModule, FindSection,
- (const char *));
+ LLDB_REGISTER_METHOD(lldb::SBSection, SBModule, FindSection, (const char *));
LLDB_REGISTER_METHOD(lldb::ByteOrder, SBModule, GetByteOrder, ());
LLDB_REGISTER_METHOD(const char *, SBModule, GetTriple, ());
LLDB_REGISTER_METHOD(uint32_t, SBModule, GetAddressByteSize, ());
- LLDB_REGISTER_METHOD(uint32_t, SBModule, GetVersion,
- (uint32_t *, uint32_t));
- LLDB_REGISTER_METHOD_CONST(lldb::SBFileSpec, SBModule, GetSymbolFileSpec,
- ());
+ LLDB_REGISTER_METHOD(uint32_t, SBModule, GetVersion, (uint32_t *, uint32_t));
+ LLDB_REGISTER_METHOD_CONST(lldb::SBFileSpec, SBModule, GetSymbolFileSpec, ());
LLDB_REGISTER_METHOD_CONST(lldb::SBAddress, SBModule,
GetObjectFileHeaderAddress, ());
LLDB_REGISTER_METHOD_CONST(lldb::SBAddress, SBModule,
GetObjectFileEntryPointAddress, ());
LLDB_REGISTER_STATIC_METHOD(uint32_t, SBModule, GetNumberAllocatedModules,
());
+ LLDB_REGISTER_STATIC_METHOD(void, SBModule, GarbageCollectAllocatedModules,
+ ());
}
-}
-}
+} // namespace repro
+} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/API/SBPlatform.cpp b/contrib/llvm-project/lldb/source/API/SBPlatform.cpp
index 7ac852488ffb..f118048156b9 100644
--- a/contrib/llvm-project/lldb/source/API/SBPlatform.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBPlatform.cpp
@@ -50,14 +50,25 @@ struct PlatformConnectOptions {
// PlatformShellCommand
struct PlatformShellCommand {
- PlatformShellCommand(const char *shell_command = nullptr)
+ PlatformShellCommand(llvm::StringRef shell_interpreter,
+ llvm::StringRef shell_command)
: m_command(), m_working_dir(), m_status(0), m_signo(0) {
- if (shell_command && shell_command[0])
- m_command = shell_command;
+ if (!shell_interpreter.empty())
+ m_shell = shell_interpreter.str();
+
+ if (!m_shell.empty() && !shell_command.empty())
+ m_command = shell_command.str();
+ }
+
+ PlatformShellCommand(llvm::StringRef shell_command = llvm::StringRef())
+ : m_shell(), m_command(), m_working_dir(), m_status(0), m_signo(0) {
+ if (!shell_command.empty())
+ m_command = shell_command.str();
}
~PlatformShellCommand() = default;
+ std::string m_shell;
std::string m_command;
std::string m_working_dir;
std::string m_output;
@@ -82,8 +93,8 @@ SBPlatformConnectOptions::SBPlatformConnectOptions(
SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; }
-SBPlatformConnectOptions &SBPlatformConnectOptions::
-operator=(const SBPlatformConnectOptions &rhs) {
+SBPlatformConnectOptions &
+SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) {
LLDB_RECORD_METHOD(
SBPlatformConnectOptions &,
SBPlatformConnectOptions, operator=,(
@@ -163,6 +174,13 @@ void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) {
}
// SBPlatformShellCommand
+SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_interpreter,
+ const char *shell_command)
+ : m_opaque_ptr(new PlatformShellCommand(shell_interpreter, shell_command)) {
+ LLDB_RECORD_CONSTRUCTOR(SBPlatformShellCommand, (const char *, const char *),
+ shell_interpreter, shell_command);
+}
+
SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command)
: m_opaque_ptr(new PlatformShellCommand(shell_command)) {
LLDB_RECORD_CONSTRUCTOR(SBPlatformShellCommand, (const char *),
@@ -178,8 +196,8 @@ SBPlatformShellCommand::SBPlatformShellCommand(
*m_opaque_ptr = *rhs.m_opaque_ptr;
}
-SBPlatformShellCommand &SBPlatformShellCommand::
-operator=(const SBPlatformShellCommand &rhs) {
+SBPlatformShellCommand &
+SBPlatformShellCommand::operator=(const SBPlatformShellCommand &rhs) {
LLDB_RECORD_METHOD(
SBPlatformShellCommand &,
@@ -200,6 +218,24 @@ void SBPlatformShellCommand::Clear() {
m_opaque_ptr->m_signo = 0;
}
+const char *SBPlatformShellCommand::GetShell() {
+ LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatformShellCommand, GetShell);
+
+ if (m_opaque_ptr->m_shell.empty())
+ return nullptr;
+ return m_opaque_ptr->m_shell.c_str();
+}
+
+void SBPlatformShellCommand::SetShell(const char *shell_interpreter) {
+ LLDB_RECORD_METHOD(void, SBPlatformShellCommand, SetShell, (const char *),
+ shell_interpreter);
+
+ if (shell_interpreter && shell_interpreter[0])
+ m_opaque_ptr->m_shell = shell_interpreter;
+ else
+ m_opaque_ptr->m_shell.clear();
+}
+
const char *SBPlatformShellCommand::GetCommand() {
LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatformShellCommand, GetCommand);
@@ -545,24 +581,25 @@ SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) {
SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) {
LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, Run,
(lldb::SBPlatformShellCommand &), shell_command);
- return LLDB_RECORD_RESULT(ExecuteConnected([&](const lldb::PlatformSP
- &platform_sp) {
- const char *command = shell_command.GetCommand();
- if (!command)
- return Status("invalid shell command (empty)");
-
- const char *working_dir = shell_command.GetWorkingDirectory();
- if (working_dir == nullptr) {
- working_dir = platform_sp->GetWorkingDirectory().GetCString();
- if (working_dir)
- shell_command.SetWorkingDirectory(working_dir);
- }
- return platform_sp->RunShellCommand(command, FileSpec(working_dir),
- &shell_command.m_opaque_ptr->m_status,
- &shell_command.m_opaque_ptr->m_signo,
- &shell_command.m_opaque_ptr->m_output,
- shell_command.m_opaque_ptr->m_timeout);
- }));
+ return LLDB_RECORD_RESULT(
+ ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
+ const char *command = shell_command.GetCommand();
+ if (!command)
+ return Status("invalid shell command (empty)");
+
+ const char *working_dir = shell_command.GetWorkingDirectory();
+ if (working_dir == nullptr) {
+ working_dir = platform_sp->GetWorkingDirectory().GetCString();
+ if (working_dir)
+ shell_command.SetWorkingDirectory(working_dir);
+ }
+ return platform_sp->RunShellCommand(
+ shell_command.m_opaque_ptr->m_shell, command, FileSpec(working_dir),
+ &shell_command.m_opaque_ptr->m_status,
+ &shell_command.m_opaque_ptr->m_signo,
+ &shell_command.m_opaque_ptr->m_output,
+ shell_command.m_opaque_ptr->m_timeout);
+ }));
}
SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {
@@ -668,8 +705,7 @@ SBEnvironment SBPlatform::GetEnvironment() {
namespace lldb_private {
namespace repro {
-template <>
-void RegisterMethods<SBPlatformConnectOptions>(Registry &R) {
+template <> void RegisterMethods<SBPlatformConnectOptions>(Registry &R) {
LLDB_REGISTER_CONSTRUCTOR(SBPlatformConnectOptions, (const char *));
LLDB_REGISTER_CONSTRUCTOR(SBPlatformConnectOptions,
(const lldb::SBPlatformConnectOptions &));
@@ -678,8 +714,7 @@ void RegisterMethods<SBPlatformConnectOptions>(Registry &R) {
SBPlatformConnectOptions, operator=,(
const lldb::SBPlatformConnectOptions &));
LLDB_REGISTER_METHOD(const char *, SBPlatformConnectOptions, GetURL, ());
- LLDB_REGISTER_METHOD(void, SBPlatformConnectOptions, SetURL,
- (const char *));
+ LLDB_REGISTER_METHOD(void, SBPlatformConnectOptions, SetURL, (const char *));
LLDB_REGISTER_METHOD(bool, SBPlatformConnectOptions, GetRsyncEnabled, ());
LLDB_REGISTER_METHOD(void, SBPlatformConnectOptions, EnableRsync,
(const char *, const char *, bool));
@@ -690,8 +725,7 @@ void RegisterMethods<SBPlatformConnectOptions>(Registry &R) {
(const char *));
}
-template <>
-void RegisterMethods<SBPlatformShellCommand>(Registry &R) {
+template <> void RegisterMethods<SBPlatformShellCommand>(Registry &R) {
LLDB_REGISTER_CONSTRUCTOR(SBPlatformShellCommand, (const char *));
LLDB_REGISTER_CONSTRUCTOR(SBPlatformShellCommand,
(const lldb::SBPlatformShellCommand &));
@@ -699,6 +733,8 @@ void RegisterMethods<SBPlatformShellCommand>(Registry &R) {
SBPlatformShellCommand &,
SBPlatformShellCommand, operator=,(const lldb::SBPlatformShellCommand &));
LLDB_REGISTER_METHOD(void, SBPlatformShellCommand, Clear, ());
+ LLDB_REGISTER_METHOD(const char *, SBPlatformShellCommand, GetShell, ());
+ LLDB_REGISTER_METHOD(void, SBPlatformShellCommand, SetShell, (const char *));
LLDB_REGISTER_METHOD(const char *, SBPlatformShellCommand, GetCommand, ());
LLDB_REGISTER_METHOD(void, SBPlatformShellCommand, SetCommand,
(const char *));
@@ -706,8 +742,7 @@ void RegisterMethods<SBPlatformShellCommand>(Registry &R) {
GetWorkingDirectory, ());
LLDB_REGISTER_METHOD(void, SBPlatformShellCommand, SetWorkingDirectory,
(const char *));
- LLDB_REGISTER_METHOD(uint32_t, SBPlatformShellCommand, GetTimeoutSeconds,
- ());
+ LLDB_REGISTER_METHOD(uint32_t, SBPlatformShellCommand, GetTimeoutSeconds, ());
LLDB_REGISTER_METHOD(void, SBPlatformShellCommand, SetTimeoutSeconds,
(uint32_t));
LLDB_REGISTER_METHOD(int, SBPlatformShellCommand, GetSignal, ());
@@ -715,15 +750,16 @@ void RegisterMethods<SBPlatformShellCommand>(Registry &R) {
LLDB_REGISTER_METHOD(const char *, SBPlatformShellCommand, GetOutput, ());
}
-template <>
-void RegisterMethods<SBPlatform>(Registry &R) {
+template <> void RegisterMethods<SBPlatform>(Registry &R) {
LLDB_REGISTER_CONSTRUCTOR(SBPlatform, ());
LLDB_REGISTER_CONSTRUCTOR(SBPlatform, (const char *));
LLDB_REGISTER_CONSTRUCTOR(SBPlatform, (const lldb::SBPlatform &));
+ LLDB_REGISTER_CONSTRUCTOR(SBPlatformShellCommand,
+ (const char *, const char *));
LLDB_REGISTER_METHOD(SBPlatform &,
SBPlatform, operator=,(const lldb::SBPlatform &));
LLDB_REGISTER_METHOD_CONST(bool, SBPlatform, IsValid, ());
- LLDB_REGISTER_METHOD_CONST(bool, SBPlatform, operator bool, ());
+ LLDB_REGISTER_METHOD_CONST(bool, SBPlatform, operator bool,());
LLDB_REGISTER_METHOD(void, SBPlatform, Clear, ());
LLDB_REGISTER_METHOD(const char *, SBPlatform, GetName, ());
LLDB_REGISTER_METHOD(const char *, SBPlatform, GetWorkingDirectory, ());
@@ -763,5 +799,5 @@ void RegisterMethods<SBPlatform>(Registry &R) {
());
}
-}
-}
+} // namespace repro
+} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/API/SBQueueItem.cpp b/contrib/llvm-project/lldb/source/API/SBQueueItem.cpp
index 0f92e2e04126..6cd9e4514caf 100644
--- a/contrib/llvm-project/lldb/source/API/SBQueueItem.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBQueueItem.cpp
@@ -80,7 +80,7 @@ SBAddress SBQueueItem::GetAddress() const {
SBAddress result;
if (m_queue_item_sp) {
- result.SetAddress(&m_queue_item_sp->GetAddress());
+ result.SetAddress(m_queue_item_sp->GetAddress());
}
return LLDB_RECORD_RESULT(result);
}
diff --git a/contrib/llvm-project/lldb/source/API/SBReproducer.cpp b/contrib/llvm-project/lldb/source/API/SBReproducer.cpp
index 0eb3429c4fef..4d25fcc4a8f6 100644
--- a/contrib/llvm-project/lldb/source/API/SBReproducer.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBReproducer.cpp
@@ -8,7 +8,6 @@
#include "SBReproducerPrivate.h"
-#include "SBReproducerPrivate.h"
#include "lldb/API/LLDB.h"
#include "lldb/API/SBAddress.h"
#include "lldb/API/SBAttachInfo.h"
@@ -30,6 +29,33 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::repro;
+SBReplayOptions::SBReplayOptions()
+ : m_opaque_up(std::make_unique<ReplayOptions>()){}
+
+SBReplayOptions::SBReplayOptions(const SBReplayOptions &rhs)
+ : m_opaque_up(std::make_unique<ReplayOptions>(*rhs.m_opaque_up)) {}
+
+SBReplayOptions::~SBReplayOptions() = default;
+
+SBReplayOptions &SBReplayOptions::operator=(const SBReplayOptions &rhs) {
+ if (this == &rhs)
+ return *this;
+ *m_opaque_up = *rhs.m_opaque_up;
+ return *this;
+}
+
+void SBReplayOptions::SetVerify(bool verify) { m_opaque_up->verify = verify; }
+
+bool SBReplayOptions::GetVerify() const { return m_opaque_up->verify; }
+
+void SBReplayOptions::SetCheckVersion(bool check) {
+ m_opaque_up->check_version = check;
+}
+
+bool SBReplayOptions::GetCheckVersion() const {
+ return m_opaque_up->check_version;
+}
+
SBRegistry::SBRegistry() {
Registry &R = *this;
@@ -163,10 +189,18 @@ const char *SBReproducer::PassiveReplay(const char *path) {
}
const char *SBReproducer::Replay(const char *path) {
- return SBReproducer::Replay(path, false);
+ SBReplayOptions options;
+ return SBReproducer::Replay(path, options);
}
const char *SBReproducer::Replay(const char *path, bool skip_version_check) {
+ SBReplayOptions options;
+ options.SetCheckVersion(!skip_version_check);
+ return SBReproducer::Replay(path, options);
+}
+
+const char *SBReproducer::Replay(const char *path,
+ const SBReplayOptions &options) {
static std::string error;
if (auto e = Reproducer::Initialize(ReproducerMode::Replay, FileSpec(path))) {
error = llvm::toString(std::move(e));
@@ -179,7 +213,7 @@ const char *SBReproducer::Replay(const char *path, bool skip_version_check) {
return error.c_str();
}
- if (!skip_version_check) {
+ if (options.GetCheckVersion()) {
llvm::Expected<std::string> version = loader->LoadBuffer<VersionProvider>();
if (!version) {
error = llvm::toString(version.takeError());
@@ -195,6 +229,30 @@ const char *SBReproducer::Replay(const char *path, bool skip_version_check) {
}
}
+ if (options.GetVerify()) {
+ bool verification_failed = false;
+ llvm::raw_string_ostream os(error);
+ auto error_callback = [&](llvm::StringRef error) {
+ verification_failed = true;
+ os << "\nerror: " << error;
+ };
+
+ auto warning_callback = [&](llvm::StringRef warning) {
+ verification_failed = true;
+ os << "\nwarning: " << warning;
+ };
+
+ auto note_callback = [&](llvm::StringRef warning) {};
+
+ Verifier verifier(loader);
+ verifier.Verify(error_callback, warning_callback, note_callback);
+
+ if (verification_failed) {
+ os.flush();
+ return error.c_str();
+ }
+ }
+
FileSpec file = loader->GetFile<SBProvider::Info>();
if (!file) {
error = "unable to get replay data from reproducer.";
@@ -207,6 +265,27 @@ const char *SBReproducer::Replay(const char *path, bool skip_version_check) {
return nullptr;
}
+const char *SBReproducer::Finalize(const char *path) {
+ static std::string error;
+ if (auto e = Reproducer::Initialize(ReproducerMode::Replay, FileSpec(path))) {
+ error = llvm::toString(std::move(e));
+ return error.c_str();
+ }
+
+ repro::Loader *loader = repro::Reproducer::Instance().GetLoader();
+ if (!loader) {
+ error = "unable to get replay loader.";
+ return error.c_str();
+ }
+
+ if (auto e = repro::Finalize(loader)) {
+ error = llvm::toString(std::move(e));
+ return error.c_str();
+ }
+
+ return nullptr;
+}
+
bool SBReproducer::Generate() {
auto &r = Reproducer::Instance();
if (auto generator = r.GetGenerator()) {
@@ -226,15 +305,19 @@ bool SBReproducer::SetAutoGenerate(bool b) {
}
const char *SBReproducer::GetPath() {
- static std::string path;
+ ConstString path;
auto &r = Reproducer::Instance();
- path = r.GetReproducerPath().GetCString();
- return path.c_str();
+ if (FileSpec reproducer_path = Reproducer::Instance().GetReproducerPath())
+ path = ConstString(r.GetReproducerPath().GetCString());
+ return path.GetCString();
}
void SBReproducer::SetWorkingDirectory(const char *path) {
if (auto *g = lldb_private::repro::Reproducer::Instance().GetGenerator()) {
- g->GetOrCreate<WorkingDirectoryProvider>().Update(path);
+ auto &wp = g->GetOrCreate<repro::WorkingDirectoryProvider>();
+ wp.SetDirectory(path);
+ auto &fp = g->GetOrCreate<repro::FileProvider>();
+ fp.RecordInterestingDirectory(wp.GetDirectory());
}
}
diff --git a/contrib/llvm-project/lldb/source/API/SBReproducerPrivate.h b/contrib/llvm-project/lldb/source/API/SBReproducerPrivate.h
index a4c6eb94627b..02ac31c2ad89 100644
--- a/contrib/llvm-project/lldb/source/API/SBReproducerPrivate.h
+++ b/contrib/llvm-project/lldb/source/API/SBReproducerPrivate.h
@@ -16,6 +16,7 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/ReproducerInstrumentation.h"
+#include "lldb/Utility/ReproducerProvider.h"
#include "llvm/ADT/DenseMap.h"
diff --git a/contrib/llvm-project/lldb/source/API/SBSymbol.cpp b/contrib/llvm-project/lldb/source/API/SBSymbol.cpp
index e4f2f3518270..eafc3e630bcd 100644
--- a/contrib/llvm-project/lldb/source/API/SBSymbol.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBSymbol.cpp
@@ -151,7 +151,7 @@ SBAddress SBSymbol::GetStartAddress() {
SBAddress addr;
if (m_opaque_ptr && m_opaque_ptr->ValueIsAddress()) {
- addr.SetAddress(&m_opaque_ptr->GetAddressRef());
+ addr.SetAddress(m_opaque_ptr->GetAddressRef());
}
return LLDB_RECORD_RESULT(addr);
}
@@ -163,7 +163,7 @@ SBAddress SBSymbol::GetEndAddress() {
if (m_opaque_ptr && m_opaque_ptr->ValueIsAddress()) {
lldb::addr_t range_size = m_opaque_ptr->GetByteSize();
if (range_size > 0) {
- addr.SetAddress(&m_opaque_ptr->GetAddressRef());
+ addr.SetAddress(m_opaque_ptr->GetAddressRef());
addr->Slide(m_opaque_ptr->GetByteSize());
}
}
diff --git a/contrib/llvm-project/lldb/source/API/SBTarget.cpp b/contrib/llvm-project/lldb/source/API/SBTarget.cpp
index b84e9f10fafe..6128c04de32b 100644
--- a/contrib/llvm-project/lldb/source/API/SBTarget.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBTarget.cpp
@@ -267,7 +267,7 @@ SBProcess SBTarget::LoadCore(const char *core_file, lldb::SBError &error) {
FileSpec filespec(core_file);
FileSystem::Instance().Resolve(filespec);
ProcessSP process_sp(target_sp->CreateProcess(
- target_sp->GetDebugger().GetListener(), "", &filespec));
+ target_sp->GetDebugger().GetListener(), "", &filespec, false));
if (process_sp) {
error.SetError(process_sp->LoadCore());
if (error.Success())
@@ -287,16 +287,24 @@ SBProcess SBTarget::LaunchSimple(char const **argv, char const **envp,
(const char **, const char **, const char *), argv, envp,
working_directory);
- char *stdin_path = nullptr;
- char *stdout_path = nullptr;
- char *stderr_path = nullptr;
- uint32_t launch_flags = 0;
- bool stop_at_entry = false;
+ TargetSP target_sp = GetSP();
+ if (!target_sp)
+ return LLDB_RECORD_RESULT(SBProcess());
+
+ SBLaunchInfo launch_info = GetLaunchInfo();
+
+ if (Module *exe_module = target_sp->GetExecutableModulePointer())
+ launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(),
+ /*add_as_first_arg*/ true);
+ if (argv)
+ launch_info.SetArguments(argv, /*append*/ true);
+ if (envp)
+ launch_info.SetEnvironmentEntries(envp, /*append*/ false);
+ if (working_directory)
+ launch_info.SetWorkingDirectory(working_directory);
+
SBError error;
- SBListener listener = GetDebugger().GetListener();
- return LLDB_RECORD_RESULT(Launch(listener, argv, envp, stdin_path,
- stdout_path, stderr_path, working_directory,
- launch_flags, stop_at_entry, error));
+ return LLDB_RECORD_RESULT(Launch(launch_info, error));
}
SBError SBTarget::Install() {
@@ -559,10 +567,11 @@ lldb::SBProcess SBTarget::ConnectRemote(SBListener &listener, const char *url,
std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
if (listener.IsValid())
process_sp =
- target_sp->CreateProcess(listener.m_opaque_sp, plugin_name, nullptr);
+ target_sp->CreateProcess(listener.m_opaque_sp, plugin_name, nullptr,
+ true);
else
process_sp = target_sp->CreateProcess(
- target_sp->GetDebugger().GetListener(), plugin_name, nullptr);
+ target_sp->GetDebugger().GetListener(), plugin_name, nullptr, true);
if (process_sp) {
sb_process.SetSP(process_sp);
@@ -778,6 +787,38 @@ SBBreakpoint SBTarget::BreakpointCreateByLocation(
return LLDB_RECORD_RESULT(sb_bp);
}
+SBBreakpoint SBTarget::BreakpointCreateByLocation(
+ const SBFileSpec &sb_file_spec, uint32_t line, uint32_t column,
+ lldb::addr_t offset, SBFileSpecList &sb_module_list,
+ bool move_to_nearest_code) {
+ LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByLocation,
+ (const lldb::SBFileSpec &, uint32_t, uint32_t,
+ lldb::addr_t, lldb::SBFileSpecList &, bool),
+ sb_file_spec, line, column, offset, sb_module_list,
+ move_to_nearest_code);
+
+ SBBreakpoint sb_bp;
+ TargetSP target_sp(GetSP());
+ if (target_sp && line != 0) {
+ 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 FileSpecList *module_list = nullptr;
+ if (sb_module_list.GetSize() > 0) {
+ module_list = sb_module_list.get();
+ }
+ sb_bp = target_sp->CreateBreakpoint(
+ module_list, *sb_file_spec, line, column, offset, check_inlines,
+ skip_prologue, internal, hardware,
+ move_to_nearest_code ? eLazyBoolYes : eLazyBoolNo);
+ }
+
+ return LLDB_RECORD_RESULT(sb_bp);
+}
+
SBBreakpoint SBTarget::BreakpointCreateByName(const char *symbol_name,
const char *module_name) {
LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByName,
@@ -1783,7 +1824,7 @@ lldb::SBSymbolContextList SBTarget::FindFunctions(const char *name,
(const char *, uint32_t), name, name_type_mask);
lldb::SBSymbolContextList sb_sc_list;
- if (!name | !name[0])
+ if (!name || !name[0])
return LLDB_RECORD_RESULT(sb_sc_list);
TargetSP target_sp(GetSP());
@@ -2480,6 +2521,9 @@ void RegisterMethods<SBTarget>(Registry &R) {
BreakpointCreateByLocation,
(const lldb::SBFileSpec &, uint32_t, uint32_t,
lldb::addr_t, lldb::SBFileSpecList &));
+ LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByLocation,
+ (const lldb::SBFileSpec &, uint32_t, uint32_t,
+ lldb::addr_t, lldb::SBFileSpecList &, bool));
LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByName,
(const char *, const char *));
LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBTarget, BreakpointCreateByName,
diff --git a/contrib/llvm-project/lldb/source/API/SBThreadPlan.cpp b/contrib/llvm-project/lldb/source/API/SBThreadPlan.cpp
index 1a947bbc2608..9af673b0f3a9 100644
--- a/contrib/llvm-project/lldb/source/API/SBThreadPlan.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBThreadPlan.cpp
@@ -53,13 +53,13 @@ using namespace lldb_private;
SBThreadPlan::SBThreadPlan() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBThreadPlan); }
SBThreadPlan::SBThreadPlan(const ThreadPlanSP &lldb_object_sp)
- : m_opaque_sp(lldb_object_sp) {
+ : m_opaque_wp(lldb_object_sp) {
LLDB_RECORD_CONSTRUCTOR(SBThreadPlan, (const lldb::ThreadPlanSP &),
lldb_object_sp);
}
SBThreadPlan::SBThreadPlan(const SBThreadPlan &rhs)
- : m_opaque_sp(rhs.m_opaque_sp) {
+ : m_opaque_wp(rhs.m_opaque_wp) {
LLDB_RECORD_CONSTRUCTOR(SBThreadPlan, (const lldb::SBThreadPlan &), rhs);
}
@@ -69,8 +69,8 @@ SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name) {
Thread *thread = sb_thread.get();
if (thread)
- m_opaque_sp = std::make_shared<ThreadPlanPython>(*thread, class_name,
- nullptr);
+ m_opaque_wp =
+ std::make_shared<ThreadPlanPython>(*thread, class_name, nullptr);
}
SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name,
@@ -81,7 +81,7 @@ SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name,
Thread *thread = sb_thread.get();
if (thread)
- m_opaque_sp = std::make_shared<ThreadPlanPython>(*thread, class_name,
+ m_opaque_wp = std::make_shared<ThreadPlanPython>(*thread, class_name,
args_data.m_impl_up.get());
}
@@ -92,14 +92,12 @@ const lldb::SBThreadPlan &SBThreadPlan::operator=(const SBThreadPlan &rhs) {
SBThreadPlan, operator=,(const lldb::SBThreadPlan &), rhs);
if (this != &rhs)
- m_opaque_sp = rhs.m_opaque_sp;
+ m_opaque_wp = rhs.m_opaque_wp;
return LLDB_RECORD_RESULT(*this);
}
// Destructor
SBThreadPlan::~SBThreadPlan() = default;
-lldb_private::ThreadPlan *SBThreadPlan::get() { return m_opaque_sp.get(); }
-
bool SBThreadPlan::IsValid() const {
LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThreadPlan, IsValid);
return this->operator bool();
@@ -107,13 +105,13 @@ bool SBThreadPlan::IsValid() const {
SBThreadPlan::operator bool() const {
LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThreadPlan, operator bool);
- return m_opaque_sp.get() != nullptr;
+ return static_cast<bool>(GetSP());
}
void SBThreadPlan::Clear() {
LLDB_RECORD_METHOD_NO_ARGS(void, SBThreadPlan, Clear);
- m_opaque_sp.reset();
+ m_opaque_wp.reset();
}
lldb::StopReason SBThreadPlan::GetStopReason() {
@@ -138,9 +136,10 @@ uint64_t SBThreadPlan::GetStopReasonDataAtIndex(uint32_t idx) {
SBThread SBThreadPlan::GetThread() const {
LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBThread, SBThreadPlan, GetThread);
- if (m_opaque_sp) {
+ ThreadPlanSP thread_plan_sp(GetSP());
+ if (thread_plan_sp) {
return LLDB_RECORD_RESULT(
- SBThread(m_opaque_sp->GetThread().shared_from_this()));
+ SBThread(thread_plan_sp->GetThread().shared_from_this()));
} else
return LLDB_RECORD_RESULT(SBThread());
}
@@ -149,50 +148,69 @@ bool SBThreadPlan::GetDescription(lldb::SBStream &description) const {
LLDB_RECORD_METHOD_CONST(bool, SBThreadPlan, GetDescription,
(lldb::SBStream &), description);
- if (m_opaque_sp) {
- m_opaque_sp->GetDescription(description.get(), eDescriptionLevelFull);
+ ThreadPlanSP thread_plan_sp(GetSP());
+ if (thread_plan_sp) {
+ thread_plan_sp->GetDescription(description.get(), eDescriptionLevelFull);
} else {
description.Printf("Empty SBThreadPlan");
}
return true;
}
-void SBThreadPlan::SetThreadPlan(const ThreadPlanSP &lldb_object_sp) {
- m_opaque_sp = lldb_object_sp;
+void SBThreadPlan::SetThreadPlan(const ThreadPlanSP &lldb_object_wp) {
+ m_opaque_wp = lldb_object_wp;
}
void SBThreadPlan::SetPlanComplete(bool success) {
LLDB_RECORD_METHOD(void, SBThreadPlan, SetPlanComplete, (bool), success);
- if (m_opaque_sp)
- m_opaque_sp->SetPlanComplete(success);
+ ThreadPlanSP thread_plan_sp(GetSP());
+ if (thread_plan_sp)
+ thread_plan_sp->SetPlanComplete(success);
}
bool SBThreadPlan::IsPlanComplete() {
LLDB_RECORD_METHOD_NO_ARGS(bool, SBThreadPlan, IsPlanComplete);
- if (m_opaque_sp)
- return m_opaque_sp->IsPlanComplete();
- else
- return true;
+ ThreadPlanSP thread_plan_sp(GetSP());
+ if (thread_plan_sp)
+ return thread_plan_sp->IsPlanComplete();
+ return true;
}
bool SBThreadPlan::IsPlanStale() {
LLDB_RECORD_METHOD_NO_ARGS(bool, SBThreadPlan, IsPlanStale);
- if (m_opaque_sp)
- return m_opaque_sp->IsPlanStale();
- else
- return true;
+ ThreadPlanSP thread_plan_sp(GetSP());
+ if (thread_plan_sp)
+ return thread_plan_sp->IsPlanStale();
+ return true;
}
bool SBThreadPlan::IsValid() {
LLDB_RECORD_METHOD_NO_ARGS(bool, SBThreadPlan, IsValid);
- if (m_opaque_sp)
- return m_opaque_sp->ValidatePlan(nullptr);
- else
- return false;
+ ThreadPlanSP thread_plan_sp(GetSP());
+ if (thread_plan_sp)
+ return thread_plan_sp->ValidatePlan(nullptr);
+ return false;
+}
+
+bool SBThreadPlan::GetStopOthers() {
+ LLDB_RECORD_METHOD_NO_ARGS(bool, SBThreadPlan, GetStopOthers);
+
+ ThreadPlanSP thread_plan_sp(GetSP());
+ if (thread_plan_sp)
+ return thread_plan_sp->StopOthers();
+ return false;
+}
+
+void SBThreadPlan::SetStopOthers(bool stop_others) {
+ LLDB_RECORD_METHOD(void, SBThreadPlan, SetStopOthers, (bool), stop_others);
+
+ ThreadPlanSP thread_plan_sp(GetSP());
+ if (thread_plan_sp)
+ thread_plan_sp->SetStopOthers(stop_others);
}
// This section allows an SBThreadPlan to push another of the common types of
@@ -220,7 +238,8 @@ SBThreadPlan SBThreadPlan::QueueThreadPlanForStepOverRange(
(lldb::SBAddress &, lldb::addr_t, lldb::SBError &),
sb_start_address, size, error);
- if (m_opaque_sp) {
+ ThreadPlanSP thread_plan_sp(GetSP());
+ if (thread_plan_sp) {
Address *start_address = sb_start_address.get();
if (!start_address) {
return LLDB_RECORD_RESULT(SBThreadPlan());
@@ -231,19 +250,18 @@ SBThreadPlan SBThreadPlan::QueueThreadPlanForStepOverRange(
start_address->CalculateSymbolContext(&sc);
Status plan_status;
- SBThreadPlan plan =
- SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepOverRange(
+ SBThreadPlan plan = SBThreadPlan(
+ thread_plan_sp->GetThread().QueueThreadPlanForStepOverRange(
false, range, sc, eAllThreads, plan_status));
if (plan_status.Fail())
error.SetErrorString(plan_status.AsCString());
else
- plan.m_opaque_sp->SetPrivate(true);
-
+ plan.GetSP()->SetPrivate(true);
+
return LLDB_RECORD_RESULT(plan);
- } else {
- return LLDB_RECORD_RESULT(SBThreadPlan());
}
+ return LLDB_RECORD_RESULT(SBThreadPlan());
}
SBThreadPlan
@@ -266,7 +284,8 @@ SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address,
(lldb::SBAddress &, lldb::addr_t, lldb::SBError &),
sb_start_address, size, error);
- if (m_opaque_sp) {
+ ThreadPlanSP thread_plan_sp(GetSP());
+ if (thread_plan_sp) {
Address *start_address = sb_start_address.get();
if (!start_address) {
return LLDB_RECORD_RESULT(SBThreadPlan());
@@ -278,18 +297,17 @@ SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address,
Status plan_status;
SBThreadPlan plan =
- SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepInRange(
+ SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepInRange(
false, range, sc, nullptr, eAllThreads, plan_status));
if (plan_status.Fail())
error.SetErrorString(plan_status.AsCString());
else
- plan.m_opaque_sp->SetPrivate(true);
+ plan.GetSP()->SetPrivate(true);
return LLDB_RECORD_RESULT(plan);
- } else {
- return LLDB_RECORD_RESULT(SBThreadPlan());
}
+ return LLDB_RECORD_RESULT(SBThreadPlan());
}
SBThreadPlan
@@ -312,26 +330,26 @@ SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,
(uint32_t, bool, lldb::SBError &), frame_idx_to_step_to,
first_insn, error);
- if (m_opaque_sp) {
+ ThreadPlanSP thread_plan_sp(GetSP());
+ if (thread_plan_sp) {
SymbolContext sc;
- sc = m_opaque_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(
+ sc = thread_plan_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(
lldb::eSymbolContextEverything);
Status plan_status;
SBThreadPlan plan =
- SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepOut(
+ SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepOut(
false, &sc, first_insn, false, eVoteYes, eVoteNoOpinion,
frame_idx_to_step_to, plan_status));
if (plan_status.Fail())
error.SetErrorString(plan_status.AsCString());
else
- plan.m_opaque_sp->SetPrivate(true);
+ plan.GetSP()->SetPrivate(true);
return LLDB_RECORD_RESULT(plan);
- } else {
- return LLDB_RECORD_RESULT(SBThreadPlan());
}
+ return LLDB_RECORD_RESULT(SBThreadPlan());
}
SBThreadPlan
@@ -350,25 +368,25 @@ SBThreadPlan SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address,
QueueThreadPlanForRunToAddress,
(lldb::SBAddress, lldb::SBError &), sb_address, error);
- if (m_opaque_sp) {
+ ThreadPlanSP thread_plan_sp(GetSP());
+ if (thread_plan_sp) {
Address *address = sb_address.get();
if (!address)
return LLDB_RECORD_RESULT(SBThreadPlan());
Status plan_status;
SBThreadPlan plan =
- SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForRunToAddress(
+ SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForRunToAddress(
false, *address, false, plan_status));
if (plan_status.Fail())
error.SetErrorString(plan_status.AsCString());
else
- plan.m_opaque_sp->SetPrivate(true);
+ plan.GetSP()->SetPrivate(true);
return LLDB_RECORD_RESULT(plan);
- } else {
- return LLDB_RECORD_RESULT(SBThreadPlan());
}
+ return LLDB_RECORD_RESULT(SBThreadPlan());
}
SBThreadPlan
@@ -389,22 +407,22 @@ SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
QueueThreadPlanForStepScripted,
(const char *, lldb::SBError &), script_class_name, error);
- if (m_opaque_sp) {
+ ThreadPlanSP thread_plan_sp(GetSP());
+ if (thread_plan_sp) {
Status plan_status;
StructuredData::ObjectSP empty_args;
SBThreadPlan plan =
- SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted(
+ SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepScripted(
false, script_class_name, empty_args, false, plan_status));
if (plan_status.Fail())
error.SetErrorString(plan_status.AsCString());
else
- plan.m_opaque_sp->SetPrivate(true);
+ plan.GetSP()->SetPrivate(true);
return LLDB_RECORD_RESULT(plan);
- } else {
- return LLDB_RECORD_RESULT(SBThreadPlan());
}
+ return LLDB_RECORD_RESULT(SBThreadPlan());
}
SBThreadPlan
@@ -416,17 +434,18 @@ SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
(const char *, lldb::SBStructuredData &, lldb::SBError &),
script_class_name, args_data, error);
- if (m_opaque_sp) {
+ ThreadPlanSP thread_plan_sp(GetSP());
+ if (thread_plan_sp) {
Status plan_status;
StructuredData::ObjectSP args_obj = args_data.m_impl_up->GetObjectSP();
SBThreadPlan plan =
- SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted(
+ SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepScripted(
false, script_class_name, args_obj, false, plan_status));
if (plan_status.Fail())
error.SetErrorString(plan_status.AsCString());
else
- plan.m_opaque_sp->SetPrivate(true);
+ plan.GetSP()->SetPrivate(true);
return LLDB_RECORD_RESULT(plan);
} else {
@@ -461,6 +480,8 @@ void RegisterMethods<SBThreadPlan>(Registry &R) {
LLDB_REGISTER_METHOD(bool, SBThreadPlan, IsPlanComplete, ());
LLDB_REGISTER_METHOD(bool, SBThreadPlan, IsPlanStale, ());
LLDB_REGISTER_METHOD(bool, SBThreadPlan, IsValid, ());
+ LLDB_REGISTER_METHOD(void, SBThreadPlan, SetStopOthers, (bool));
+ LLDB_REGISTER_METHOD(bool, SBThreadPlan, GetStopOthers, ());
LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
QueueThreadPlanForStepOverRange,
(lldb::SBAddress &, lldb::addr_t));
diff --git a/contrib/llvm-project/lldb/source/API/SBType.cpp b/contrib/llvm-project/lldb/source/API/SBType.cpp
index 852630f2d01a..550c4b065914 100644
--- a/contrib/llvm-project/lldb/source/API/SBType.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBType.cpp
@@ -9,6 +9,7 @@
#include "lldb/API/SBType.h"
#include "SBReproducerPrivate.h"
#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBModule.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBTypeEnumMember.h"
#include "lldb/Core/Mangled.h"
@@ -212,10 +213,8 @@ SBType SBType::GetArrayElementType() {
if (!IsValid())
return LLDB_RECORD_RESULT(SBType());
- CompilerType canonical_type =
- m_opaque_sp->GetCompilerType(true).GetCanonicalType();
- return LLDB_RECORD_RESULT(
- SBType(TypeImplSP(new TypeImpl(canonical_type.GetArrayElementType()))));
+ return LLDB_RECORD_RESULT(SBType(TypeImplSP(new TypeImpl(
+ m_opaque_sp->GetCompilerType(true).GetArrayElementType(nullptr)))));
}
SBType SBType::GetArrayType(uint64_t size) {
@@ -272,6 +271,14 @@ bool SBType::IsAnonymousType() {
return m_opaque_sp->GetCompilerType(true).IsAnonymousType();
}
+bool SBType::IsScopedEnumerationType() {
+ LLDB_RECORD_METHOD_NO_ARGS(bool, SBType, IsScopedEnumerationType);
+
+ if (!IsValid())
+ return false;
+ return m_opaque_sp->GetCompilerType(true).IsScopedEnumerationType();
+}
+
lldb::SBType SBType::GetFunctionReturnType() {
LLDB_RECORD_METHOD_NO_ARGS(lldb::SBType, SBType, GetFunctionReturnType);
@@ -337,6 +344,16 @@ lldb::SBType SBType::GetCanonicalType() {
return LLDB_RECORD_RESULT(SBType());
}
+SBType SBType::GetEnumerationIntegerType() {
+ LLDB_RECORD_METHOD_NO_ARGS(lldb::SBType, SBType, GetEnumerationIntegerType);
+
+ if (IsValid()) {
+ return LLDB_RECORD_RESULT(
+ SBType(m_opaque_sp->GetCompilerType(true).GetEnumerationIntegerType()));
+ }
+ return LLDB_RECORD_RESULT(SBType());
+}
+
lldb::BasicType SBType::GetBasicType() {
LLDB_RECORD_METHOD_NO_ARGS(lldb::BasicType, SBType, GetBasicType);
@@ -495,6 +512,17 @@ uint32_t SBType::GetTypeFlags() {
return m_opaque_sp->GetCompilerType(true).GetTypeInfo();
}
+lldb::SBModule SBType::GetModule() {
+ LLDB_RECORD_METHOD_NO_ARGS(lldb::SBModule, SBType, GetModule);
+
+ lldb::SBModule sb_module;
+ if (!IsValid())
+ return LLDB_RECORD_RESULT(sb_module);
+
+ sb_module.SetSP(m_opaque_sp->GetModule());
+ return LLDB_RECORD_RESULT(sb_module);
+}
+
const char *SBType::GetName() {
LLDB_RECORD_METHOD_NO_ARGS(const char *, SBType, GetName);
@@ -925,6 +953,7 @@ void RegisterMethods<SBType>(Registry &R) {
LLDB_REGISTER_METHOD(bool, SBType, IsPolymorphicClass, ());
LLDB_REGISTER_METHOD(bool, SBType, IsTypedefType, ());
LLDB_REGISTER_METHOD(bool, SBType, IsAnonymousType, ());
+ LLDB_REGISTER_METHOD(bool, SBType, IsScopedEnumerationType, ());
LLDB_REGISTER_METHOD(lldb::SBType, SBType, GetFunctionReturnType, ());
LLDB_REGISTER_METHOD(lldb::SBTypeList, SBType, GetFunctionArgumentTypes,
());
@@ -933,6 +962,7 @@ void RegisterMethods<SBType>(Registry &R) {
GetMemberFunctionAtIndex, (uint32_t));
LLDB_REGISTER_METHOD(lldb::SBType, SBType, GetUnqualifiedType, ());
LLDB_REGISTER_METHOD(lldb::SBType, SBType, GetCanonicalType, ());
+ LLDB_REGISTER_METHOD(lldb::SBType, SBType, GetEnumerationIntegerType, ());
LLDB_REGISTER_METHOD(lldb::BasicType, SBType, GetBasicType, ());
LLDB_REGISTER_METHOD(lldb::SBType, SBType, GetBasicType, (lldb::BasicType));
LLDB_REGISTER_METHOD(uint32_t, SBType, GetNumberOfDirectBaseClasses, ());
@@ -950,6 +980,7 @@ void RegisterMethods<SBType>(Registry &R) {
(uint32_t));
LLDB_REGISTER_METHOD(bool, SBType, IsTypeComplete, ());
LLDB_REGISTER_METHOD(uint32_t, SBType, GetTypeFlags, ());
+ LLDB_REGISTER_METHOD(lldb::SBModule, SBType, GetModule, ());
LLDB_REGISTER_METHOD(const char *, SBType, GetName, ());
LLDB_REGISTER_METHOD(const char *, SBType, GetDisplayTypeName, ());
LLDB_REGISTER_METHOD(lldb::TypeClass, SBType, GetTypeClass, ());
diff --git a/contrib/llvm-project/lldb/source/API/SBValue.cpp b/contrib/llvm-project/lldb/source/API/SBValue.cpp
index 7485b0ee1838..0a95cf41263d 100644
--- a/contrib/llvm-project/lldb/source/API/SBValue.cpp
+++ b/contrib/llvm-project/lldb/source/API/SBValue.cpp
@@ -333,7 +333,7 @@ size_t SBValue::GetByteSize() {
ValueLocker locker;
lldb::ValueObjectSP value_sp(GetSP(locker));
if (value_sp) {
- result = value_sp->GetByteSize();
+ result = value_sp->GetByteSize().getValueOr(0);
}
return result;
@@ -1356,7 +1356,7 @@ lldb::SBAddress SBValue::GetAddress() {
}
}
- return LLDB_RECORD_RESULT(SBAddress(new Address(addr)));
+ return LLDB_RECORD_RESULT(SBAddress(addr));
}
lldb::SBData SBValue::GetPointeeData(uint32_t item_idx, uint32_t item_count) {
diff --git a/contrib/llvm-project/lldb/source/API/SystemInitializerFull.cpp b/contrib/llvm-project/lldb/source/API/SystemInitializerFull.cpp
index 7f95e7acf62a..0530f94580b3 100644
--- a/contrib/llvm-project/lldb/source/API/SystemInitializerFull.cpp
+++ b/contrib/llvm-project/lldb/source/API/SystemInitializerFull.cpp
@@ -14,6 +14,8 @@
#include "lldb/Host/Host.h"
#include "lldb/Initialization/SystemInitializerCommon.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Target/ProcessTrace.h"
+#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/Timer.h"
#include "llvm/Support/TargetSelect.h"
@@ -33,8 +35,16 @@ SystemInitializerFull::SystemInitializerFull() = default;
SystemInitializerFull::~SystemInitializerFull() = default;
llvm::Error SystemInitializerFull::Initialize() {
- if (auto e = SystemInitializerCommon::Initialize())
- return e;
+ llvm::Error error = SystemInitializerCommon::Initialize();
+ if (error) {
+ // During active replay, the ::Initialize call is replayed like any other
+ // SB API call and the return value is ignored. Since we can't intercept
+ // this, we terminate here before the uninitialized debugger inevitably
+ // crashes.
+ if (repro::Reproducer::Instance().IsReplaying())
+ llvm::report_fatal_error(std::move(error));
+ return error;
+ }
// Initialize LLVM and Clang
llvm::InitializeAllTargets();
@@ -45,6 +55,9 @@ llvm::Error SystemInitializerFull::Initialize() {
#define LLDB_PLUGIN(p) LLDB_PLUGIN_INITIALIZE(p);
#include "Plugins/Plugins.def"
+ // Initialize plug-ins in core LLDB
+ ProcessTrace::Initialize();
+
// Scan for any system or user LLDB plug-ins
PluginManager::Initialize();
@@ -56,11 +69,11 @@ llvm::Error SystemInitializerFull::Initialize() {
}
void SystemInitializerFull::Terminate() {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
-
Debugger::SettingsTerminate();
+ // Terminate plug-ins in core LLDB
+ ProcessTrace::Terminate();
+
// Terminate and unload and loaded system or user LLDB plug-ins
PluginManager::Terminate();
diff --git a/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp b/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp
index 317dfa231094..d7bca308ca99 100644
--- a/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp
+++ b/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp
@@ -51,7 +51,7 @@ Breakpoint::Breakpoint(Target &target, SearchFilterSP &filter_sp,
: m_being_created(true), m_hardware(hardware), m_target(target),
m_filter_sp(filter_sp), m_resolver_sp(resolver_sp),
m_options_up(new BreakpointOptions(true)), m_locations(*this),
- m_resolve_indirect_symbols(resolve_indirect_symbols), m_hit_count(0) {
+ m_resolve_indirect_symbols(resolve_indirect_symbols), m_hit_counter() {
m_being_created = false;
}
@@ -61,7 +61,7 @@ Breakpoint::Breakpoint(Target &new_target, const Breakpoint &source_bp)
m_options_up(new BreakpointOptions(*source_bp.m_options_up)),
m_locations(*this),
m_resolve_indirect_symbols(source_bp.m_resolve_indirect_symbols),
- m_hit_count(0) {}
+ m_hit_counter() {}
// Destructor
Breakpoint::~Breakpoint() = default;
@@ -144,8 +144,7 @@ lldb::BreakpointSP Breakpoint::CreateFromStructuredData(
bool success = breakpoint_dict->GetValueForKeyAsDictionary(
BreakpointResolver::GetSerializationKey(), resolver_dict);
if (!success) {
- error.SetErrorStringWithFormat(
- "Breakpoint data missing toplevel resolver key");
+ error.SetErrorString("Breakpoint data missing toplevel resolver key");
return result_sp;
}
@@ -242,15 +241,12 @@ bool Breakpoint::SerializedBreakpointMatchesNames(
return false;
size_t num_names = names_array->GetSize();
- std::vector<std::string>::iterator begin = names.begin();
- std::vector<std::string>::iterator end = names.end();
for (size_t i = 0; i < num_names; i++) {
llvm::StringRef name;
if (names_array->GetItemAtIndexAsString(i, name)) {
- if (std::find(begin, end, name) != end) {
+ if (llvm::is_contained(names, name))
return true;
- }
}
}
return false;
@@ -342,7 +338,7 @@ bool Breakpoint::IgnoreCountShouldStop() {
return true;
}
-uint32_t Breakpoint::GetHitCount() const { return m_hit_count; }
+uint32_t Breakpoint::GetHitCount() const { return m_hit_counter.GetValue(); }
bool Breakpoint::IsOneShot() const { return m_options_up->IsOneShot(); }
@@ -512,7 +508,6 @@ void Breakpoint::ModulesChanged(ModuleList &module_list, bool load,
"delete_locations: %i\n",
module_list.GetSize(), load, delete_locations);
- std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
if (load) {
// The logic for handling new modules is:
// 1) If the filter rejects this module, then skip it. 2) Run through the
@@ -529,7 +524,7 @@ void Breakpoint::ModulesChanged(ModuleList &module_list, bool load,
// them after the locations pass. Have to do it this way because resolving
// breakpoints will add new locations potentially.
- for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
+ for (ModuleSP module_sp : module_list.Modules()) {
bool seen = false;
if (!m_filter_sp->ModulePasses(module_sp))
continue;
@@ -593,9 +588,7 @@ void Breakpoint::ModulesChanged(ModuleList &module_list, bool load,
else
removed_locations_event = nullptr;
- size_t num_modules = module_list.GetSize();
- for (size_t i = 0; i < num_modules; i++) {
- ModuleSP module_sp(module_list.GetModuleAtIndexUnlocked(i));
+ for (ModuleSP module_sp : module_list.Modules()) {
if (m_filter_sp->ModulePasses(module_sp)) {
size_t loc_idx = 0;
size_t num_locations = m_locations.GetSize();
diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp
index 293baf4ad1c7..a37abcfa52ab 100644
--- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp
+++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp
@@ -96,7 +96,7 @@ bool BreakpointID::StringIsBreakpointName(llvm::StringRef str, Status &error) {
error.Clear();
if (str.empty())
{
- error.SetErrorStringWithFormat("Empty breakpoint names are not allowed");
+ error.SetErrorString("Empty breakpoint names are not allowed");
return false;
}
diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointIDList.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointIDList.cpp
index 705bc5ee1c8d..e6a5dceeb93b 100644
--- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointIDList.cpp
+++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointIDList.cpp
@@ -220,10 +220,10 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target,
((start_loc_id != LLDB_INVALID_BREAK_ID) &&
(end_loc_id == LLDB_INVALID_BREAK_ID))) {
new_args.Clear();
- result.AppendErrorWithFormat("Invalid breakpoint id range: Either "
- "both ends of range must specify"
- " a breakpoint location, or neither can "
- "specify a breakpoint location.\n");
+ result.AppendError("Invalid breakpoint id range: Either "
+ "both ends of range must specify"
+ " a breakpoint location, or neither can "
+ "specify a breakpoint location.");
result.SetStatus(eReturnStatusFailed);
return;
}
diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp
index 93d54c051ee5..d3d6ea08bdb3 100644
--- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp
+++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp
@@ -31,11 +31,10 @@ 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_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_up(), m_bp_site_sp(), m_condition_mutex() {
+ m_owner(owner), m_options_up(), m_bp_site_sp(), m_condition_mutex(),
+ m_condition_hash(0), m_loc_id(loc_id), m_hit_counter() {
if (check_for_resolver) {
Symbol *symbol = m_address.CalculateSymbolContextSymbol();
if (symbol && symbol->IsIndirect()) {
@@ -332,7 +331,7 @@ bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
return ret;
}
-uint32_t BreakpointLocation::GetIgnoreCount() {
+uint32_t BreakpointLocation::GetIgnoreCount() const {
return GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
->GetIgnoreCount();
}
@@ -417,16 +416,16 @@ bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) {
void BreakpointLocation::BumpHitCount() {
if (IsEnabled()) {
// Step our hit count, and also step the hit count of the owner.
- IncrementHitCount();
- m_owner.IncrementHitCount();
+ m_hit_counter.Increment();
+ m_owner.m_hit_counter.Increment();
}
}
void BreakpointLocation::UndoBumpHitCount() {
if (IsEnabled()) {
// Step our hit count, and also step the hit count of the owner.
- DecrementHitCount();
- m_owner.DecrementHitCount();
+ m_hit_counter.Decrement();
+ m_owner.m_hit_counter.Decrement();
}
}
@@ -593,12 +592,15 @@ void BreakpointLocation::GetDescription(Stream *s,
}
}
+ bool is_resolved = IsResolved();
+ bool is_hardware = is_resolved && m_bp_site_sp->IsHardware();
+
if (level == lldb::eDescriptionLevelVerbose) {
s->EOL();
s->Indent();
- s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
+ s->Printf("resolved = %s\n", is_resolved ? "true" : "false");
s->Indent();
- s->Printf("hardware = %s\n", IsHardware() ? "true" : "false");
+ s->Printf("hardware = %s\n", is_hardware ? "true" : "false");
s->Indent();
s->Printf("hit count = %-4u\n", GetHitCount());
@@ -609,8 +611,8 @@ void BreakpointLocation::GetDescription(Stream *s,
}
s->IndentLess();
} else if (level != eDescriptionLevelInitial) {
- s->Printf(", %sresolved, %shit count = %u ", (IsResolved() ? "" : "un"),
- (IsHardware() ? "hardware, " : ""), GetHitCount());
+ s->Printf(", %sresolved, %shit count = %u ", (is_resolved ? "" : "un"),
+ (is_hardware ? "hardware, " : ""), GetHitCount());
if (m_options_up) {
m_options_up->GetDescription(s, level);
}
@@ -621,6 +623,11 @@ void BreakpointLocation::Dump(Stream *s) const {
if (s == nullptr)
return;
+ bool is_resolved = IsResolved();
+ bool is_hardware = is_resolved && m_bp_site_sp->IsHardware();
+ auto hardware_index = is_resolved ?
+ m_bp_site_sp->GetHardwareIndex() : LLDB_INVALID_INDEX32;
+
lldb::tid_t tid = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
->GetThreadSpecNoCreate()->GetTID();
s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64
@@ -631,8 +638,7 @@ void BreakpointLocation::Dump(Stream *s) const {
(m_options_up ? m_options_up->IsEnabled() : m_owner.IsEnabled())
? "enabled "
: "disabled",
- IsHardware() ? "hardware" : "software", GetHardwareIndex(),
- GetHitCount(),
+ is_hardware ? "hardware" : "software", hardware_index, GetHitCount(),
GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
->GetIgnoreCount());
}
diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp
index 0ce7b0f852e8..f6bb7633d0a9 100644
--- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp
+++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp
@@ -319,7 +319,7 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData(
else {
ScriptInterpreter *interp = target.GetDebugger().GetScriptInterpreter();
if (!interp) {
- error.SetErrorStringWithFormat(
+ error.SetErrorString(
"Can't set script commands - no script interpreter");
return nullptr;
}
diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp
index 7c03a0745ac6..cfd073367b00 100644
--- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp
+++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp
@@ -81,8 +81,7 @@ BreakpointResolverSP BreakpointResolver::CreateFromStructuredData(
GetSerializationSubclassKey(), subclass_name);
if (!success) {
- error.SetErrorStringWithFormat(
- "Resolver data missing subclass resolver key");
+ error.SetErrorString("Resolver data missing subclass resolver key");
return result_sp;
}
diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverAddress.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverAddress.cpp
index 2c56912b56af..3187e8464f6f 100644
--- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverAddress.cpp
+++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverAddress.cpp
@@ -87,7 +87,6 @@ BreakpointResolverAddress::SerializeToStructuredData() {
}
return WrapOptionsDict(options_dict_sp);
- return StructuredData::ObjectSP();
}
void BreakpointResolverAddress::ResolveBreakpoint(SearchFilter &filter) {
diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
index 22a4b4ae33ae..5ca4ef5834e0 100644
--- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
+++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
@@ -187,6 +187,14 @@ void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list,
// is 0, then we can't do this calculation. That can happen if
// GetStartLineSourceInfo gets an error, or if the first line number in
// the function really is 0 - which happens for some languages.
+
+ // But only do this calculation if the line number we found in the SC
+ // was different from the one requested in the source file. If we actually
+ // found an exact match it must be valid.
+
+ if (m_line_number == sc.line_entry.line)
+ continue;
+
const int decl_line_is_too_late_fudge = 1;
if (line && m_line_number < line - decl_line_is_too_late_fudge) {
LLDB_LOG(log, "removing symbol context at {0}:{1}", file, line);
diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp
index 25f5bb3f6eed..6fab20af5e59 100644
--- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp
+++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp
@@ -108,7 +108,7 @@ BreakpointResolver *BreakpointResolverName::CreateFromStructuredData(
success =
options_dict.GetValueForKeyAsInteger(GetKey(OptionNames::Offset), offset);
if (!success) {
- error.SetErrorStringWithFormat("BRN::CFSD: Missing offset entry.");
+ error.SetErrorString("BRN::CFSD: Missing offset entry.");
return nullptr;
}
@@ -116,7 +116,7 @@ BreakpointResolver *BreakpointResolverName::CreateFromStructuredData(
success = options_dict.GetValueForKeyAsBoolean(
GetKey(OptionNames::SkipPrologue), skip_prologue);
if (!success) {
- error.SetErrorStringWithFormat("BRN::CFSD: Missing Skip prologue entry.");
+ error.SetErrorString("BRN::CFSD: Missing Skip prologue entry.");
return nullptr;
}
@@ -131,15 +131,14 @@ BreakpointResolver *BreakpointResolverName::CreateFromStructuredData(
success = options_dict.GetValueForKeyAsArray(
GetKey(OptionNames::SymbolNameArray), names_array);
if (!success) {
- error.SetErrorStringWithFormat("BRN::CFSD: Missing symbol names entry.");
+ error.SetErrorString("BRN::CFSD: Missing symbol names entry.");
return nullptr;
}
StructuredData::Array *names_mask_array;
success = options_dict.GetValueForKeyAsArray(
GetKey(OptionNames::NameMaskArray), names_mask_array);
if (!success) {
- error.SetErrorStringWithFormat(
- "BRN::CFSD: Missing symbol names mask entry.");
+ error.SetErrorString("BRN::CFSD: Missing symbol names mask entry.");
return nullptr;
}
diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSite.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSite.cpp
index a33fd0a1c462..fb3f0cd06897 100644
--- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSite.cpp
+++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSite.cpp
@@ -21,7 +21,7 @@ using namespace lldb_private;
BreakpointSite::BreakpointSite(BreakpointSiteList *list,
const BreakpointLocationSP &owner,
lldb::addr_t addr, bool use_hardware)
- : StoppointLocation(GetNextID(), addr, 0, use_hardware),
+ : StoppointSite(GetNextID(), addr, 0, use_hardware),
m_type(eSoftware), // Process subclasses need to set this correctly using
// SetType()
m_saved_opcode(), m_trap_opcode(),
@@ -48,7 +48,7 @@ break_id_t BreakpointSite::GetNextID() {
// should continue.
bool BreakpointSite::ShouldStop(StoppointCallbackContext *context) {
- IncrementHitCount();
+ m_hit_counter.Increment();
// ShouldStop can do a lot of work, and might even come come back and hit
// this breakpoint site again. So don't hold the m_owners_mutex the whole
// while. Instead make a local copy of the collection and call ShouldStop on
@@ -156,51 +156,46 @@ void BreakpointSite::BumpHitCounts() {
}
}
-void BreakpointSite::SetHardwareIndex(uint32_t index) {
- std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
- for (BreakpointLocationSP loc_sp : m_owners.BreakpointLocations()) {
- loc_sp->SetHardwareIndex(index);
- }
-}
-
bool BreakpointSite::IntersectsRange(lldb::addr_t addr, size_t size,
lldb::addr_t *intersect_addr,
size_t *intersect_size,
size_t *opcode_offset) const {
- // We only use software traps for software breakpoints
- if (!IsHardware()) {
- if (m_byte_size > 0) {
- const lldb::addr_t bp_end_addr = m_addr + m_byte_size;
- const lldb::addr_t end_addr = addr + size;
- // Is the breakpoint end address before the passed in start address?
- if (bp_end_addr <= addr)
- return false;
- // Is the breakpoint start address after passed in end address?
- if (end_addr <= m_addr)
- return false;
- if (intersect_addr || intersect_size || opcode_offset) {
- if (m_addr < addr) {
- if (intersect_addr)
- *intersect_addr = addr;
- if (intersect_size)
- *intersect_size =
- std::min<lldb::addr_t>(bp_end_addr, end_addr) - addr;
- if (opcode_offset)
- *opcode_offset = addr - m_addr;
- } else {
- if (intersect_addr)
- *intersect_addr = m_addr;
- if (intersect_size)
- *intersect_size =
- std::min<lldb::addr_t>(bp_end_addr, end_addr) - m_addr;
- if (opcode_offset)
- *opcode_offset = 0;
- }
- }
- return true;
+ // The function should be called only for software breakpoints.
+ lldbassert(GetType() == Type::eSoftware);
+
+ if (m_byte_size == 0)
+ return false;
+
+ const lldb::addr_t bp_end_addr = m_addr + m_byte_size;
+ const lldb::addr_t end_addr = addr + size;
+ // Is the breakpoint end address before the passed in start address?
+ if (bp_end_addr <= addr)
+ return false;
+
+ // Is the breakpoint start address after passed in end address?
+ if (end_addr <= m_addr)
+ return false;
+
+ if (intersect_addr || intersect_size || opcode_offset) {
+ if (m_addr < addr) {
+ if (intersect_addr)
+ *intersect_addr = addr;
+ if (intersect_size)
+ *intersect_size =
+ std::min<lldb::addr_t>(bp_end_addr, end_addr) - addr;
+ if (opcode_offset)
+ *opcode_offset = addr - m_addr;
+ } else {
+ if (intersect_addr)
+ *intersect_addr = m_addr;
+ if (intersect_size)
+ *intersect_size =
+ std::min<lldb::addr_t>(bp_end_addr, end_addr) - m_addr;
+ if (opcode_offset)
+ *opcode_offset = 0;
}
}
- return false;
+ return true;
}
size_t
diff --git a/contrib/llvm-project/lldb/source/Breakpoint/StoppointLocation.cpp b/contrib/llvm-project/lldb/source/Breakpoint/StoppointLocation.cpp
deleted file mode 100644
index 5bb4c7854840..000000000000
--- a/contrib/llvm-project/lldb/source/Breakpoint/StoppointLocation.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-//===-- StoppointLocation.cpp ---------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Breakpoint/StoppointLocation.h"
-
-
-using namespace lldb;
-using namespace lldb_private;
-
-// StoppointLocation constructor
-StoppointLocation::StoppointLocation(break_id_t bid, addr_t addr, bool hardware)
- : m_loc_id(bid), m_addr(addr), m_hardware(hardware),
- m_hardware_index(LLDB_INVALID_INDEX32), m_byte_size(0), m_hit_count(0) {}
-
-StoppointLocation::StoppointLocation(break_id_t bid, addr_t addr,
- uint32_t byte_size, bool hardware)
- : m_loc_id(bid), m_addr(addr), m_hardware(hardware),
- m_hardware_index(LLDB_INVALID_INDEX32), m_byte_size(byte_size),
- m_hit_count(0) {}
-
-// Destructor
-StoppointLocation::~StoppointLocation() {}
-
-void StoppointLocation::DecrementHitCount() {
- assert(m_hit_count > 0);
- --m_hit_count;
-}
diff --git a/contrib/llvm-project/lldb/source/Breakpoint/StoppointSite.cpp b/contrib/llvm-project/lldb/source/Breakpoint/StoppointSite.cpp
new file mode 100644
index 000000000000..ba8c48326bdb
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Breakpoint/StoppointSite.cpp
@@ -0,0 +1,23 @@
+//===-- StoppointSite.cpp ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Breakpoint/StoppointSite.h"
+
+
+using namespace lldb;
+using namespace lldb_private;
+
+StoppointSite::StoppointSite(break_id_t id, addr_t addr, bool hardware)
+ : m_id(id), m_addr(addr), m_is_hardware_required(hardware),
+ m_hardware_index(LLDB_INVALID_INDEX32), m_byte_size(0), m_hit_counter() {}
+
+StoppointSite::StoppointSite(break_id_t id, addr_t addr,
+ uint32_t byte_size, bool hardware)
+ : m_id(id), m_addr(addr), m_is_hardware_required(hardware),
+ m_hardware_index(LLDB_INVALID_INDEX32), m_byte_size(byte_size),
+ m_hit_counter() {}
diff --git a/contrib/llvm-project/lldb/source/Breakpoint/Watchpoint.cpp b/contrib/llvm-project/lldb/source/Breakpoint/Watchpoint.cpp
index df73c6a17230..29ae1ef3df26 100644
--- a/contrib/llvm-project/lldb/source/Breakpoint/Watchpoint.cpp
+++ b/contrib/llvm-project/lldb/source/Breakpoint/Watchpoint.cpp
@@ -25,7 +25,7 @@ using namespace lldb_private;
Watchpoint::Watchpoint(Target &target, lldb::addr_t addr, uint32_t size,
const CompilerType *type, bool hardware)
- : StoppointLocation(0, addr, size, hardware), m_target(target),
+ : StoppointSite(0, addr, size, hardware), m_target(target),
m_enabled(false), m_is_hardware(hardware), m_is_watch_variable(false),
m_is_ephemeral(false), m_disabled_count(0), m_watch_read(0),
m_watch_write(0), m_watch_was_read(0), m_watch_was_written(0),
@@ -93,9 +93,10 @@ void Watchpoint::SetWatchSpec(const std::string &str) {
m_watch_spec_str = str;
}
-// Override default impl of StoppointLocation::IsHardware() since m_is_hardware
-// member field is more accurate.
-bool Watchpoint::IsHardware() const { return m_is_hardware; }
+bool Watchpoint::IsHardware() const {
+ lldbassert(m_is_hardware || !HardwareRequired());
+ return m_is_hardware;
+}
bool Watchpoint::IsWatchVariable() const { return m_is_watch_variable; }
@@ -123,12 +124,12 @@ bool Watchpoint::CaptureWatchedValue(const ExecutionContext &exe_ctx) {
void Watchpoint::IncrementFalseAlarmsAndReviseHitCount() {
++m_false_alarms;
if (m_false_alarms) {
- if (m_hit_count >= m_false_alarms) {
- m_hit_count -= m_false_alarms;
+ if (m_hit_counter.GetValue() >= m_false_alarms) {
+ m_hit_counter.Decrement(m_false_alarms);
m_false_alarms = 0;
} else {
- m_false_alarms -= m_hit_count;
- m_hit_count = 0;
+ m_false_alarms -= m_hit_counter.GetValue();
+ m_hit_counter.Reset();
}
}
}
@@ -137,7 +138,7 @@ void Watchpoint::IncrementFalseAlarmsAndReviseHitCount() {
// should continue.
bool Watchpoint::ShouldStop(StoppointCallbackContext *context) {
- IncrementHitCount();
+ m_hit_counter.Increment();
return IsEnabled();
}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp b/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp
index 48df77357201..0ea6d4288169 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp
@@ -9,16 +9,21 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSet.h"
+#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Variable.h"
+#include "lldb/Target/Language.h"
+#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Thread.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/TildeExpressionResolver.h"
@@ -52,6 +57,7 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks(
{eDiskDirectoryCompletion, CommandCompletions::DiskDirectories},
{eSymbolCompletion, CommandCompletions::Symbols},
{eModuleCompletion, CommandCompletions::Modules},
+ {eModuleUUIDCompletion, CommandCompletions::ModuleUUIDs},
{eSettingsNameCompletion, CommandCompletions::SettingsNames},
{ePlatformPluginCompletion, CommandCompletions::PlatformPluginNames},
{eArchitectureCompletion, CommandCompletions::ArchitectureNames},
@@ -59,6 +65,19 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks(
{eRegisterCompletion, CommandCompletions::Registers},
{eBreakpointCompletion, CommandCompletions::Breakpoints},
{eProcessPluginCompletion, CommandCompletions::ProcessPluginNames},
+ {eDisassemblyFlavorCompletion, CommandCompletions::DisassemblyFlavors},
+ {eTypeLanguageCompletion, CommandCompletions::TypeLanguages},
+ {eFrameIndexCompletion, CommandCompletions::FrameIndexes},
+ {eStopHookIDCompletion, CommandCompletions::StopHookIDs},
+ {eThreadIndexCompletion, CommandCompletions::ThreadIndexes},
+ {eWatchPointIDCompletion, CommandCompletions::WatchPointIDs},
+ {eBreakpointNameCompletion, CommandCompletions::BreakpointNames},
+ {eProcessIDCompletion, CommandCompletions::ProcessIDs},
+ {eProcessNameCompletion, CommandCompletions::ProcessNames},
+ {eRemoteDiskFileCompletion, CommandCompletions::RemoteDiskFiles},
+ {eRemoteDiskDirectoryCompletion,
+ CommandCompletions::RemoteDiskDirectories},
+ {eTypeCategoryNameCompletion, CommandCompletions::TypeCategoryNames},
{eNoCompletion, nullptr} // This one has to be last in the list.
};
@@ -472,6 +491,24 @@ void CommandCompletions::DiskDirectories(const llvm::Twine &partial_file_name,
DiskFilesOrDirectories(partial_file_name, true, matches, Resolver);
}
+void CommandCompletions::RemoteDiskFiles(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ lldb::PlatformSP platform_sp =
+ interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
+ if (platform_sp)
+ platform_sp->AutoCompleteDiskFileOrDirectory(request, false);
+}
+
+void CommandCompletions::RemoteDiskDirectories(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ lldb::PlatformSP platform_sp =
+ interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
+ if (platform_sp)
+ platform_sp->AutoCompleteDiskFileOrDirectory(request, true);
+}
+
void CommandCompletions::Modules(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
@@ -486,6 +523,24 @@ void CommandCompletions::Modules(CommandInterpreter &interpreter,
}
}
+void CommandCompletions::ModuleUUIDs(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ const ExecutionContext &exe_ctx = interpreter.GetExecutionContext();
+ if (!exe_ctx.HasTargetScope())
+ return;
+
+ exe_ctx.GetTargetPtr()->GetImages().ForEach(
+ [&request](const lldb::ModuleSP &module) {
+ StreamString strm;
+ module->GetDescription(strm.AsRawOstream(),
+ lldb::eDescriptionLevelInitial);
+ request.TryCompleteCurrentArg(module->GetUUID().GetAsString(),
+ strm.GetString());
+ return true;
+ });
+}
+
void CommandCompletions::Symbols(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
@@ -588,9 +643,154 @@ void CommandCompletions::Breakpoints(CommandInterpreter &interpreter,
}
}
+void CommandCompletions::BreakpointNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ lldb::TargetSP target = interpreter.GetDebugger().GetSelectedTarget();
+ if (!target)
+ return;
+
+ std::vector<std::string> name_list;
+ target->GetBreakpointNames(name_list);
+
+ for (const std::string &name : name_list)
+ request.TryCompleteCurrentArg(name);
+}
+
void CommandCompletions::ProcessPluginNames(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
PluginManager::AutoCompleteProcessName(request.GetCursorArgumentPrefix(),
request);
-} \ No newline at end of file
+}
+void CommandCompletions::DisassemblyFlavors(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ // Currently the only valid options for disassemble -F are default, and for
+ // Intel architectures, att and intel.
+ static const char *flavors[] = {"default", "att", "intel"};
+ for (const char *flavor : flavors) {
+ request.TryCompleteCurrentArg(flavor);
+ }
+}
+
+void CommandCompletions::ProcessIDs(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ lldb::PlatformSP platform_sp(interpreter.GetPlatform(true));
+ if (!platform_sp)
+ return;
+ ProcessInstanceInfoList process_infos;
+ ProcessInstanceInfoMatch match_info;
+ platform_sp->FindProcesses(match_info, process_infos);
+ for (const ProcessInstanceInfo &info : process_infos)
+ request.TryCompleteCurrentArg(std::to_string(info.GetProcessID()),
+ info.GetNameAsStringRef());
+}
+
+void CommandCompletions::ProcessNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ lldb::PlatformSP platform_sp(interpreter.GetPlatform(true));
+ if (!platform_sp)
+ return;
+ ProcessInstanceInfoList process_infos;
+ ProcessInstanceInfoMatch match_info;
+ platform_sp->FindProcesses(match_info, process_infos);
+ for (const ProcessInstanceInfo &info : process_infos)
+ request.TryCompleteCurrentArg(info.GetNameAsStringRef());
+}
+
+void CommandCompletions::TypeLanguages(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ for (int bit :
+ Language::GetLanguagesSupportingTypeSystems().bitvector.set_bits()) {
+ request.TryCompleteCurrentArg(
+ Language::GetNameForLanguageType(static_cast<lldb::LanguageType>(bit)));
+ }
+}
+
+void CommandCompletions::FrameIndexes(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ const ExecutionContext &exe_ctx = interpreter.GetExecutionContext();
+ if (!exe_ctx.HasProcessScope())
+ return;
+
+ lldb::ThreadSP thread_sp = exe_ctx.GetThreadSP();
+ const uint32_t frame_num = thread_sp->GetStackFrameCount();
+ for (uint32_t i = 0; i < frame_num; ++i) {
+ lldb::StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(i);
+ StreamString strm;
+ frame_sp->Dump(&strm, false, true);
+ request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
+ }
+}
+
+void CommandCompletions::StopHookIDs(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ const lldb::TargetSP target_sp =
+ interpreter.GetExecutionContext().GetTargetSP();
+ if (!target_sp)
+ return;
+
+ const size_t num = target_sp->GetNumStopHooks();
+ for (size_t idx = 0; idx < num; ++idx) {
+ StreamString strm;
+ // The value 11 is an offset to make the completion description looks
+ // neater.
+ strm.SetIndentLevel(11);
+ const Target::StopHookSP stophook_sp = target_sp->GetStopHookAtIndex(idx);
+ stophook_sp->GetDescription(&strm, lldb::eDescriptionLevelInitial);
+ request.TryCompleteCurrentArg(std::to_string(stophook_sp->GetID()),
+ strm.GetString());
+ }
+}
+
+void CommandCompletions::ThreadIndexes(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ const ExecutionContext &exe_ctx = interpreter.GetExecutionContext();
+ if (!exe_ctx.HasProcessScope())
+ return;
+
+ ThreadList &threads = exe_ctx.GetProcessPtr()->GetThreadList();
+ lldb::ThreadSP thread_sp;
+ for (uint32_t idx = 0; (thread_sp = threads.GetThreadAtIndex(idx)); ++idx) {
+ StreamString strm;
+ thread_sp->GetStatus(strm, 0, 1, 1, true);
+ request.TryCompleteCurrentArg(std::to_string(thread_sp->GetIndexID()),
+ strm.GetString());
+ }
+}
+
+void CommandCompletions::WatchPointIDs(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ const ExecutionContext &exe_ctx = interpreter.GetExecutionContext();
+ if (!exe_ctx.HasTargetScope())
+ return;
+
+ const WatchpointList &wp_list = exe_ctx.GetTargetPtr()->GetWatchpointList();
+ const size_t wp_num = wp_list.GetSize();
+ for (size_t idx = 0; idx < wp_num; ++idx) {
+ const lldb::WatchpointSP wp_sp = wp_list.GetByIndex(idx);
+ StreamString strm;
+ wp_sp->Dump(&strm);
+ request.TryCompleteCurrentArg(std::to_string(wp_sp->GetID()),
+ strm.GetString());
+ }
+}
+
+void CommandCompletions::TypeCategoryNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ DataVisualization::Categories::ForEach(
+ [&request](const lldb::TypeCategoryImplSP &category_sp) {
+ request.TryCompleteCurrentArg(category_sp->GetName(),
+ category_sp->GetDescription());
+ return true;
+ });
+}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp
index be7ef8a1b60b..0844c56cef2f 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -17,6 +17,7 @@
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
#include "lldb/Interpreter/OptionValueBoolean.h"
+#include "lldb/Interpreter/OptionValueFileColonLine.h"
#include "lldb/Interpreter/OptionValueString.h"
#include "lldb/Interpreter/OptionValueUInt64.h"
#include "lldb/Interpreter/Options.h"
@@ -443,7 +444,22 @@ public:
case 'X':
m_source_regex_func_names.insert(std::string(option_arg));
break;
-
+
+ case 'y':
+ {
+ OptionValueFileColonLine value;
+ Status fcl_err = value.SetValueFromString(option_arg);
+ if (!fcl_err.Success()) {
+ error.SetErrorStringWithFormat(
+ "Invalid value for file:line specifier: %s",
+ fcl_err.AsCString());
+ } else {
+ m_filenames.AppendIfUnique(value.GetFileSpec());
+ m_line_num = value.GetLineNumber();
+ m_column = value.GetColumnNumber();
+ }
+ } break;
+
default:
llvm_unreachable("Unimplemented option");
}
@@ -1407,7 +1423,8 @@ public:
class CommandOptions : public Options {
public:
- CommandOptions() : Options(), m_use_dummy(false), m_force(false) {}
+ CommandOptions() : Options(), m_use_dummy(false), m_force(false),
+ m_delete_disabled(false) {}
~CommandOptions() override = default;
@@ -1424,6 +1441,10 @@ public:
case 'D':
m_use_dummy = true;
break;
+
+ case 'd':
+ m_delete_disabled = true;
+ break;
default:
llvm_unreachable("Unimplemented option");
@@ -1435,6 +1456,7 @@ public:
void OptionParsingStarting(ExecutionContext *execution_context) override {
m_use_dummy = false;
m_force = false;
+ m_delete_disabled = false;
}
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
@@ -1444,16 +1466,18 @@ public:
// Instance variables to hold the values for command options.
bool m_use_dummy;
bool m_force;
+ bool m_delete_disabled;
};
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
-
+ result.Clear();
+
std::unique_lock<std::recursive_mutex> lock;
target.GetBreakpointList().GetListMutex(lock);
- const BreakpointList &breakpoints = target.GetBreakpointList();
+ BreakpointList &breakpoints = target.GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
@@ -1463,7 +1487,7 @@ protected:
return false;
}
- if (command.empty()) {
+ if (command.empty() && !m_options.m_delete_disabled) {
if (!m_options.m_force &&
!m_interpreter.Confirm(
"About to delete all breakpoints, do you want to do that?",
@@ -1479,10 +1503,34 @@ protected:
} else {
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, &target, result, &valid_bp_ids,
- BreakpointName::Permissions::PermissionKinds::deletePerm);
-
+
+ if (m_options.m_delete_disabled) {
+ BreakpointIDList excluded_bp_ids;
+
+ if (!command.empty()) {
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, &target, result, &excluded_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::deletePerm);
+ }
+ for (auto breakpoint_sp : breakpoints.Breakpoints()) {
+ if (!breakpoint_sp->IsEnabled() && breakpoint_sp->AllowDelete()) {
+ BreakpointID bp_id(breakpoint_sp->GetID());
+ size_t pos = 0;
+ if (!excluded_bp_ids.FindBreakpointID(bp_id, &pos))
+ valid_bp_ids.AddBreakpointID(breakpoint_sp->GetID());
+ }
+ }
+ if (valid_bp_ids.GetSize() == 0) {
+ result.AppendError("No disabled breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, &target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::deletePerm);
+ }
+
if (result.Succeeded()) {
int delete_count = 0;
int disable_count = 0;
@@ -2081,7 +2129,79 @@ public:
return llvm::makeArrayRef(g_breakpoint_read_options);
}
- // Instance variables to hold the values for command options.
+ void HandleOptionArgumentCompletion(
+ CompletionRequest &request, OptionElementVector &opt_element_vector,
+ int opt_element_index, CommandInterpreter &interpreter) override {
+ int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
+ int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
+
+ switch (GetDefinitions()[opt_defs_index].short_option) {
+ case 'f':
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ interpreter, CommandCompletions::eDiskFileCompletion, request,
+ nullptr);
+ break;
+
+ case 'N':
+ llvm::Optional<FileSpec> file_spec;
+ const llvm::StringRef dash_f("-f");
+ for (int arg_idx = 0; arg_idx < opt_arg_pos; arg_idx++) {
+ if (dash_f == request.GetParsedLine().GetArgumentAtIndex(arg_idx)) {
+ file_spec.emplace(
+ request.GetParsedLine().GetArgumentAtIndex(arg_idx + 1));
+ break;
+ }
+ }
+ if (!file_spec)
+ return;
+
+ FileSystem::Instance().Resolve(*file_spec);
+ Status error;
+ StructuredData::ObjectSP input_data_sp =
+ StructuredData::ParseJSONFromFile(*file_spec, error);
+ if (!error.Success())
+ return;
+
+ StructuredData::Array *bkpt_array = input_data_sp->GetAsArray();
+ if (!bkpt_array)
+ return;
+
+ const size_t num_bkpts = bkpt_array->GetSize();
+ for (size_t i = 0; i < num_bkpts; i++) {
+ StructuredData::ObjectSP bkpt_object_sp =
+ bkpt_array->GetItemAtIndex(i);
+ if (!bkpt_object_sp)
+ return;
+
+ StructuredData::Dictionary *bkpt_dict =
+ bkpt_object_sp->GetAsDictionary();
+ if (!bkpt_dict)
+ return;
+
+ StructuredData::ObjectSP bkpt_data_sp =
+ bkpt_dict->GetValueForKey(Breakpoint::GetSerializationKey());
+ if (!bkpt_data_sp)
+ return;
+
+ bkpt_dict = bkpt_data_sp->GetAsDictionary();
+ if (!bkpt_dict)
+ return;
+
+ StructuredData::Array *names_array;
+
+ if (!bkpt_dict->GetValueForKeyAsArray("Names", names_array))
+ return;
+
+ size_t num_names = names_array->GetSize();
+
+ for (size_t i = 0; i < num_names; i++) {
+ llvm::StringRef name;
+ if (names_array->GetItemAtIndexAsString(i, name))
+ request.TryCompleteCurrentArg(name);
+ }
+ }
+ }
+ }
std::string m_filename;
std::vector<std::string> m_names;
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
index 45df86589011..caaf3bfb482f 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
@@ -141,12 +141,16 @@ Example Python one-line breakpoint command:
(lldb) breakpoint command add -s python 1
Enter your Python command(s). Type 'DONE' to end.
-> print "Hit this breakpoint!"
-> DONE
+def function (frame, bp_loc, internal_dict):
+ """frame: the lldb.SBFrame for the location at which you stopped
+ bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
+ internal_dict: an LLDB support object not to be used"""
+ print("Hit this breakpoint!")
+ DONE
As a convenience, this also works for a short Python one-liner:
-(lldb) breakpoint command add -s python 1 -o 'import time; print time.asctime()'
+(lldb) breakpoint command add -s python 1 -o 'import time; print(time.asctime())'
(lldb) run
Launching '.../a.out' (x86_64)
(lldb) Fri Sep 10 12:17:45 2010
@@ -164,21 +168,14 @@ Example multiple line Python breakpoint command:
(lldb) breakpoint command add -s p 1
Enter your Python command(s). Type 'DONE' to end.
-> global bp_count
-> bp_count = bp_count + 1
-> print "Hit this breakpoint " + repr(bp_count) + " times!"
-> DONE
-
-Example multiple line Python breakpoint command, using function definition:
-
-(lldb) breakpoint command add -s python 1
-Enter your Python command(s). Type 'DONE' to end.
-> def breakpoint_output (bp_no):
-> out_string = "Hit breakpoint number " + repr (bp_no)
-> print out_string
-> return True
-> breakpoint_output (1)
-> DONE
+def function (frame, bp_loc, internal_dict):
+ """frame: the lldb.SBFrame for the location at which you stopped
+ bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
+ internal_dict: an LLDB support object not to be used"""
+ global bp_count
+ bp_count = bp_count + 1
+ print("Hit this breakpoint " + repr(bp_count) + " times!")
+ DONE
)"
"In this case, since there is a reference to a global variable, \
@@ -417,22 +414,23 @@ protected:
// to set or collect command callback. Otherwise, call the methods
// associated with this object.
if (m_options.m_use_script_language) {
+ Status error;
ScriptInterpreter *script_interp = GetDebugger().GetScriptInterpreter(
/*can_create=*/true, m_options.m_script_language);
// Special handling for one-liner specified inline.
if (m_options.m_use_one_liner) {
- script_interp->SetBreakpointCommandCallback(
+ error = script_interp->SetBreakpointCommandCallback(
m_bp_options_vec, m_options.m_one_liner.c_str());
} else if (!m_func_options.GetName().empty()) {
- Status error = script_interp->SetBreakpointCommandCallbackFunction(
+ error = script_interp->SetBreakpointCommandCallbackFunction(
m_bp_options_vec, m_func_options.GetName().c_str(),
m_func_options.GetStructuredData());
- if (!error.Success())
- result.SetError(error);
} else {
script_interp->CollectDataForBreakpointCommandCallback(
m_bp_options_vec, result);
}
+ if (!error.Success())
+ result.SetError(error);
} else {
// Special handling for one-liner specified inline.
if (m_options.m_use_one_liner)
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp
index d77e69c6f6a6..3b3cdde6ab9a 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp
@@ -6,15 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/StringRef.h"
-
#include "CommandObjectCommands.h"
#include "CommandObjectHelp.h"
+#include "CommandObjectRegexCommand.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/Interpreter/CommandHistory.h"
#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/CommandObjectRegexCommand.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionValueBoolean.h"
@@ -24,161 +22,13 @@
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/StringList.h"
+#include "llvm/ADT/StringRef.h"
using namespace lldb;
using namespace lldb_private;
// CommandObjectCommandsSource
-#define LLDB_OPTIONS_history
-#include "CommandOptions.inc"
-
-class CommandObjectCommandsHistory : public CommandObjectParsed {
-public:
- CommandObjectCommandsHistory(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "command history",
- "Dump the history of commands in this session.\n"
- "Commands in the history list can be run again "
- "using \"!<INDEX>\". \"!-<OFFSET>\" will re-run "
- "the command that is <OFFSET> commands from the end"
- " of the list (counting the current command).",
- nullptr),
- m_options() {}
-
- ~CommandObjectCommandsHistory() override = default;
-
- Options *GetOptions() override { return &m_options; }
-
-protected:
- class CommandOptions : public Options {
- public:
- CommandOptions()
- : Options(), m_start_idx(0), m_stop_idx(0), m_count(0), m_clear(false) {
- }
-
- ~CommandOptions() override = default;
-
- Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
- ExecutionContext *execution_context) override {
- Status error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option) {
- case 'c':
- error = m_count.SetValueFromString(option_arg, eVarSetOperationAssign);
- break;
- case 's':
- if (option_arg == "end") {
- m_start_idx.SetCurrentValue(UINT64_MAX);
- m_start_idx.SetOptionWasSet();
- } else
- error = m_start_idx.SetValueFromString(option_arg,
- eVarSetOperationAssign);
- break;
- case 'e':
- error =
- m_stop_idx.SetValueFromString(option_arg, eVarSetOperationAssign);
- break;
- case 'C':
- m_clear.SetCurrentValue(true);
- m_clear.SetOptionWasSet();
- break;
- default:
- llvm_unreachable("Unimplemented option");
- }
-
- return error;
- }
-
- void OptionParsingStarting(ExecutionContext *execution_context) override {
- m_start_idx.Clear();
- m_stop_idx.Clear();
- m_count.Clear();
- m_clear.Clear();
- }
-
- llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
- return llvm::makeArrayRef(g_history_options);
- }
-
- // Instance variables to hold the values for command options.
-
- OptionValueUInt64 m_start_idx;
- OptionValueUInt64 m_stop_idx;
- OptionValueUInt64 m_count;
- OptionValueBoolean m_clear;
- };
-
- bool DoExecute(Args &command, CommandReturnObject &result) override {
- if (m_options.m_clear.GetCurrentValue() &&
- m_options.m_clear.OptionWasSet()) {
- m_interpreter.GetCommandHistory().Clear();
- result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
- } else {
- if (m_options.m_start_idx.OptionWasSet() &&
- m_options.m_stop_idx.OptionWasSet() &&
- m_options.m_count.OptionWasSet()) {
- result.AppendError("--count, --start-index and --end-index cannot be "
- "all specified in the same invocation");
- result.SetStatus(lldb::eReturnStatusFailed);
- } else {
- std::pair<bool, uint64_t> start_idx(
- m_options.m_start_idx.OptionWasSet(),
- m_options.m_start_idx.GetCurrentValue());
- std::pair<bool, uint64_t> stop_idx(
- m_options.m_stop_idx.OptionWasSet(),
- m_options.m_stop_idx.GetCurrentValue());
- std::pair<bool, uint64_t> count(m_options.m_count.OptionWasSet(),
- m_options.m_count.GetCurrentValue());
-
- const CommandHistory &history(m_interpreter.GetCommandHistory());
-
- if (start_idx.first && start_idx.second == UINT64_MAX) {
- if (count.first) {
- start_idx.second = history.GetSize() - count.second;
- stop_idx.second = history.GetSize() - 1;
- } else if (stop_idx.first) {
- start_idx.second = stop_idx.second;
- stop_idx.second = history.GetSize() - 1;
- } else {
- start_idx.second = 0;
- stop_idx.second = history.GetSize() - 1;
- }
- } else {
- if (!start_idx.first && !stop_idx.first && !count.first) {
- start_idx.second = 0;
- stop_idx.second = history.GetSize() - 1;
- } else if (start_idx.first) {
- if (count.first) {
- stop_idx.second = start_idx.second + count.second - 1;
- } else if (!stop_idx.first) {
- stop_idx.second = history.GetSize() - 1;
- }
- } else if (stop_idx.first) {
- if (count.first) {
- if (stop_idx.second >= count.second)
- start_idx.second = stop_idx.second - count.second + 1;
- else
- start_idx.second = 0;
- }
- } else /* if (count.first) */
- {
- start_idx.second = 0;
- stop_idx.second = count.second - 1;
- }
- }
- history.Dump(result.GetOutputStream(), start_idx.second,
- stop_idx.second);
- }
- }
- return result.Succeeded();
- }
-
- CommandOptions m_options;
-};
-
-// CommandObjectCommandsSource
-
#define LLDB_OPTIONS_source
#include "CommandOptions.inc"
@@ -614,7 +464,7 @@ protected:
OptionArgVectorSP(new OptionArgVector);
if (CommandObjectSP cmd_obj_sp =
- m_interpreter.GetCommandSPExact(cmd_obj.GetCommandName(), false)) {
+ m_interpreter.GetCommandSPExact(cmd_obj.GetCommandName())) {
if (m_interpreter.AliasExists(alias_command) ||
m_interpreter.UserCommandExists(alias_command)) {
result.AppendWarningWithFormat(
@@ -708,10 +558,9 @@ protected:
if (!args.empty()) {
CommandObjectSP tmp_sp =
- m_interpreter.GetCommandSPExact(cmd_obj->GetCommandName(), false);
+ m_interpreter.GetCommandSPExact(cmd_obj->GetCommandName());
if (use_subcommand)
- tmp_sp = m_interpreter.GetCommandSPExact(sub_cmd_obj->GetCommandName(),
- false);
+ tmp_sp = m_interpreter.GetCommandSPExact(sub_cmd_obj->GetCommandName());
args.GetCommandString(args_string);
}
@@ -767,6 +616,17 @@ public:
~CommandObjectCommandsUnalias() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (!m_interpreter.HasCommands() || request.GetCursorIndex() != 0)
+ return;
+
+ for (const auto &ent : m_interpreter.GetAliases()) {
+ request.TryCompleteCurrentArg(ent.first, ent.second->GetHelp());
+ }
+ }
+
protected:
bool DoExecute(Args &args, CommandReturnObject &result) override {
CommandObject::CommandMap::iterator pos;
@@ -848,6 +708,18 @@ public:
~CommandObjectCommandsDelete() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (!m_interpreter.HasCommands() || request.GetCursorIndex() != 0)
+ return;
+
+ for (const auto &ent : m_interpreter.GetCommands()) {
+ if (ent.second->IsRemovable())
+ request.TryCompleteCurrentArg(ent.first, ent.second->GetHelp());
+ }
+ }
+
protected:
bool DoExecute(Args &args, CommandReturnObject &result) override {
CommandObject::CommandMap::iterator pos;
@@ -1119,7 +991,7 @@ protected:
std::string subst(std::string(regex_sed.substr(
second_separator_char_pos + 1,
third_separator_char_pos - second_separator_char_pos - 1)));
- m_regex_cmd_up->AddRegexCommand(regex.c_str(), subst.c_str());
+ m_regex_cmd_up->AddRegexCommand(regex, subst);
}
return error;
}
@@ -1399,6 +1271,9 @@ protected:
case 'r':
// NO-OP
break;
+ case 'c':
+ relative_to_command_file = true;
+ break;
default:
llvm_unreachable("Unimplemented option");
}
@@ -1407,11 +1282,13 @@ protected:
}
void OptionParsingStarting(ExecutionContext *execution_context) override {
+ relative_to_command_file = false;
}
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
return llvm::makeArrayRef(g_script_import_options);
}
+ bool relative_to_command_file = false;
};
bool DoExecute(Args &command, CommandReturnObject &result) override {
@@ -1421,6 +1298,17 @@ protected:
return false;
}
+ FileSpec source_dir = {};
+ if (m_options.relative_to_command_file) {
+ source_dir = GetDebugger().GetCommandInterpreter().GetCurrentSourceDir();
+ if (!source_dir) {
+ result.AppendError("command script import -c can only be specified "
+ "from a command file");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
for (auto &entry : command.entries()) {
Status error;
@@ -1435,7 +1323,7 @@ protected:
// more)
m_exe_ctx.Clear();
if (GetDebugger().GetScriptInterpreter()->LoadScriptingModule(
- entry.c_str(), init_session, error)) {
+ entry.c_str(), init_session, error, nullptr, source_dir)) {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else {
result.AppendErrorWithFormat("module importing failed: %s",
@@ -1850,8 +1738,6 @@ CommandObjectMultiwordCommands::CommandObjectMultiwordCommands(
CommandObjectSP(new CommandObjectCommandsDelete(interpreter)));
LoadSubCommand(
"regex", CommandObjectSP(new CommandObjectCommandsAddRegex(interpreter)));
- LoadSubCommand("history", CommandObjectSP(
- new CommandObjectCommandsHistory(interpreter)));
LoadSubCommand(
"script",
CommandObjectSP(new CommandObjectMultiwordCommandsScript(interpreter)));
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp
index b23adb087b49..58eaa3f973cb 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp
@@ -304,11 +304,8 @@ void CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
return;
ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
-
- Target *target = exe_ctx.GetTargetPtr();
-
- if (!target)
- target = &GetDummyTarget();
+ Target *exe_target = exe_ctx.GetTargetPtr();
+ Target &target = exe_target ? *exe_target : GetDummyTarget();
unsigned cursor_pos = request.GetRawCursorPos();
// Get the full user input including the suffix. The suffix is necessary
@@ -342,7 +339,7 @@ void CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
auto language = exe_ctx.GetFrameRef().GetLanguage();
Status error;
- lldb::UserExpressionSP expr(target->GetUserExpressionForLanguage(
+ lldb::UserExpressionSP expr(target.GetUserExpressionForLanguage(
code, llvm::StringRef(), language, UserExpression::eResultTypeAny,
options, nullptr, error));
if (error.Fail())
@@ -411,22 +408,19 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr,
// command object DoExecute has finished when doing multi-line expression
// that use an input reader...
ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
-
- Target *target = exe_ctx.GetTargetPtr();
-
- if (!target)
- target = &GetDummyTarget();
+ Target *exe_target = exe_ctx.GetTargetPtr();
+ Target &target = exe_target ? *exe_target : GetDummyTarget();
lldb::ValueObjectSP result_valobj_sp;
StackFrame *frame = exe_ctx.GetFramePtr();
- const EvaluateExpressionOptions options = GetEvalOptions(*target);
- ExpressionResults success = target->EvaluateExpression(
+ const EvaluateExpressionOptions options = GetEvalOptions(target);
+ 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 (!m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts()) {
+ if (!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());
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp
index 6ebad9b5c488..a656a99a1c71 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp
@@ -291,17 +291,12 @@ public:
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
- if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0)
+ if (request.GetCursorIndex() != 0)
return;
- lldb::ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
- const uint32_t frame_num = thread_sp->GetStackFrameCount();
- for (uint32_t i = 0; i < frame_num; ++i) {
- lldb::StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(i);
- StreamString strm;
- frame_sp->Dump(&strm, false, true);
- request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
- }
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eFrameIndexCompletion,
+ request, nullptr);
}
Options *GetOptions() override { return &m_options; }
@@ -898,12 +893,14 @@ bool CommandObjectFrameRecognizerAdd::DoExecute(Args &command,
RegularExpressionSP(new RegularExpression(m_options.m_module));
auto func =
RegularExpressionSP(new RegularExpression(m_options.m_symbols.front()));
- StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, func);
+ GetSelectedOrDummyTarget().GetFrameRecognizerManager().AddRecognizer(
+ recognizer_sp, module, func);
} else {
auto module = ConstString(m_options.m_module);
std::vector<ConstString> symbols(m_options.m_symbols.begin(),
m_options.m_symbols.end());
- StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, symbols);
+ GetSelectedOrDummyTarget().GetFrameRecognizerManager().AddRecognizer(
+ recognizer_sp, module, symbols);
}
#endif
@@ -921,7 +918,9 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- StackFrameRecognizerManager::RemoveAllRecognizers();
+ GetSelectedOrDummyTarget()
+ .GetFrameRecognizerManager()
+ .RemoveAllRecognizers();
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
@@ -941,7 +940,7 @@ public:
if (request.GetCursorIndex() != 0)
return;
- StackFrameRecognizerManager::ForEach(
+ GetSelectedOrDummyTarget().GetFrameRecognizerManager().ForEach(
[&request](uint32_t rid, std::string rname, std::string module,
llvm::ArrayRef<lldb_private::ConstString> symbols,
bool regexp) {
@@ -973,7 +972,9 @@ protected:
return false;
}
- StackFrameRecognizerManager::RemoveAllRecognizers();
+ GetSelectedOrDummyTarget()
+ .GetFrameRecognizerManager()
+ .RemoveAllRecognizers();
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
@@ -993,7 +994,14 @@ protected:
return false;
}
- StackFrameRecognizerManager::RemoveRecognizerWithID(recognizer_id);
+ if (!GetSelectedOrDummyTarget()
+ .GetFrameRecognizerManager()
+ .RemoveRecognizerWithID(recognizer_id)) {
+ result.AppendErrorWithFormat("'%s' is not a valid recognizer id.\n",
+ command.GetArgumentAtIndex(0));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
@@ -1011,7 +1019,7 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
bool any_printed = false;
- StackFrameRecognizerManager::ForEach(
+ GetSelectedOrDummyTarget().GetFrameRecognizerManager().ForEach(
[&result, &any_printed](
uint32_t recognizer_id, std::string name, std::string module,
llvm::ArrayRef<ConstString> symbols, bool regexp) {
@@ -1106,8 +1114,9 @@ protected:
return false;
}
- auto recognizer =
- StackFrameRecognizerManager::GetRecognizerForFrame(frame_sp);
+ auto recognizer = GetSelectedOrDummyTarget()
+ .GetFrameRecognizerManager()
+ .GetRecognizerForFrame(frame_sp);
Stream &output_stream = result.GetOutputStream();
output_stream.Printf("frame %d ", frame_index);
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp
index 474c37710149..7d5c642d0131 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp
@@ -33,8 +33,7 @@
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/StreamString.h"
-
-
+#include "llvm/Support/MathExtras.h"
#include <cinttypes>
#include <memory>
@@ -1281,29 +1280,6 @@ public:
Options *GetOptions() override { return &m_option_group; }
- bool UIntValueIsValidForSize(uint64_t uval64, size_t total_byte_size) {
- if (total_byte_size > 8)
- return false;
-
- if (total_byte_size == 8)
- return true;
-
- const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1;
- return uval64 <= max;
- }
-
- bool SIntValueIsValidForSize(int64_t sval64, size_t total_byte_size) {
- if (total_byte_size > 8)
- return false;
-
- if (total_byte_size == 8)
- return true;
-
- const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1;
- const int64_t min = ~(max);
- return min <= sval64 && sval64 <= max;
- }
-
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
// No need to check "process" for validity as eCommandRequiresProcess
@@ -1449,7 +1425,7 @@ protected:
"'%s' is not a valid hex string value.\n", entry.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
- } else if (!UIntValueIsValidForSize(uval64, item_byte_size)) {
+ } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
result.AppendErrorWithFormat("Value 0x%" PRIx64
" is too large to fit in a %" PRIu64
" byte unsigned integer value.\n",
@@ -1477,7 +1453,7 @@ protected:
"'%s' is not a valid binary string value.\n", entry.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
- } else if (!UIntValueIsValidForSize(uval64, item_byte_size)) {
+ } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
result.AppendErrorWithFormat("Value 0x%" PRIx64
" is too large to fit in a %" PRIu64
" byte unsigned integer value.\n",
@@ -1516,7 +1492,7 @@ protected:
"'%s' is not a valid signed decimal value.\n", entry.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
- } else if (!SIntValueIsValidForSize(sval64, item_byte_size)) {
+ } else if (!llvm::isIntN(item_byte_size * 8, sval64)) {
result.AppendErrorWithFormat(
"Value %" PRIi64 " is too large or small to fit in a %" PRIu64
" byte signed integer value.\n",
@@ -1535,7 +1511,7 @@ protected:
entry.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
- } else if (!UIntValueIsValidForSize(uval64, item_byte_size)) {
+ } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
result.AppendErrorWithFormat("Value %" PRIu64
" is too large to fit in a %" PRIu64
" byte unsigned integer value.\n",
@@ -1552,7 +1528,7 @@ protected:
"'%s' is not a valid octal string value.\n", entry.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
- } else if (!UIntValueIsValidForSize(uval64, item_byte_size)) {
+ } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
result.AppendErrorWithFormat("Value %" PRIo64
" is too large to fit in a %" PRIu64
" byte unsigned integer value.\n",
@@ -1687,63 +1663,72 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
ProcessSP process_sp = m_exe_ctx.GetProcessSP();
- if (process_sp) {
- Status error;
- lldb::addr_t load_addr = m_prev_end_addr;
+ if (!process_sp) {
m_prev_end_addr = LLDB_INVALID_ADDRESS;
+ result.AppendError("invalid process");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ Status 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);
+ return false;
+ }
- 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());
+ if (argc == 1) {
+ auto load_addr_str = command[0].ref();
+ load_addr = OptionArgParser::ToAddress(&m_exe_ctx, load_addr_str,
+ LLDB_INVALID_ADDRESS, &error);
+ if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS) {
+ result.AppendErrorWithFormat("invalid address argument \"%s\": %s\n",
+ command[0].c_str(), error.AsCString());
result.SetStatus(eReturnStatusFailed);
- } else {
- if (command.GetArgumentCount() == 1) {
- auto load_addr_str = command[0].ref();
- load_addr = OptionArgParser::ToAddress(&m_exe_ctx, load_addr_str,
- LLDB_INVALID_ADDRESS, &error);
- if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS) {
- result.AppendErrorWithFormat(
- "invalid address argument \"%s\": %s\n", command[0].c_str(),
- error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- }
- }
+ return false;
+ }
+ }
- lldb_private::MemoryRegionInfo range_info;
- error = process_sp->GetMemoryRegionInfo(load_addr, range_info);
- if (error.Success()) {
- lldb_private::Address addr;
- ConstString name = range_info.GetName();
- 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.AppendMessageWithFormatv(
- "[{0:x16}-{1:x16}) {2:r}{3:w}{4:x}{5}{6}{7}{8}\n",
- range_info.GetRange().GetRangeBase(),
- range_info.GetRange().GetRangeEnd(), range_info.GetReadable(),
- range_info.GetWritable(), range_info.GetExecutable(),
- name ? " " : "", name, section_name ? " " : "", section_name);
- m_prev_end_addr = range_info.GetRange().GetRangeEnd();
- result.SetStatus(eReturnStatusSuccessFinishResult);
- } else {
- result.SetStatus(eReturnStatusFailed);
- result.AppendErrorWithFormat("%s\n", error.AsCString());
+ lldb_private::MemoryRegionInfo range_info;
+ error = process_sp->GetMemoryRegionInfo(load_addr, range_info);
+ if (error.Success()) {
+ lldb_private::Address addr;
+ ConstString name = range_info.GetName();
+ 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();
}
}
- } else {
- m_prev_end_addr = LLDB_INVALID_ADDRESS;
- result.AppendError("invalid process");
- result.SetStatus(eReturnStatusFailed);
+
+ result.AppendMessageWithFormatv(
+ "[{0:x16}-{1:x16}) {2:r}{3:w}{4:x}{5}{6}{7}{8}",
+ range_info.GetRange().GetRangeBase(),
+ range_info.GetRange().GetRangeEnd(), range_info.GetReadable(),
+ range_info.GetWritable(), range_info.GetExecutable(), name ? " " : "",
+ name, section_name ? " " : "", section_name);
+ MemoryRegionInfo::OptionalBool memory_tagged =
+ range_info.GetMemoryTagged();
+ if (memory_tagged == MemoryRegionInfo::OptionalBool::eYes)
+ result.AppendMessage("memory tagging: enabled");
+
+ m_prev_end_addr = range_info.GetRange().GetRangeEnd();
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
}
- return result.Succeeded();
+
+ result.SetStatus(eReturnStatusFailed);
+ result.AppendErrorWithFormat("%s\n", error.AsCString());
+ return false;
}
const char *GetRepeatCommand(Args &current_command_args,
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp
index 9033cfebf46b..0f20a1d88bd9 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp
@@ -261,11 +261,32 @@ CommandObjectProxy::CommandObjectProxy(CommandInterpreter &interpreter,
CommandObjectProxy::~CommandObjectProxy() = default;
+Options *CommandObjectProxy::GetOptions() {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetOptions();
+ return CommandObject::GetOptions();
+}
+
+llvm::StringRef CommandObjectProxy::GetHelp() {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetHelp();
+ return CommandObject::GetHelp();
+}
+
+llvm::StringRef CommandObjectProxy::GetSyntax() {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetSyntax();
+ return CommandObject::GetSyntax();
+}
+
llvm::StringRef CommandObjectProxy::GetHelpLong() {
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
return proxy_command->GetHelpLong();
- return llvm::StringRef();
+ return CommandObject::GetHelpLong();
}
bool CommandObjectProxy::IsRemovable() const {
@@ -293,7 +314,9 @@ CommandObjectMultiword *CommandObjectProxy::GetAsMultiwordCommand() {
void CommandObjectProxy::GenerateHelpText(Stream &result) {
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
- return proxy_command->GenerateHelpText(result);
+ proxy_command->GenerateHelpText(result);
+ else
+ CommandObject::GenerateHelpText(result);
}
lldb::CommandObjectSP
@@ -345,13 +368,6 @@ bool CommandObjectProxy::WantsCompletion() {
return false;
}
-Options *CommandObjectProxy::GetOptions() {
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->GetOptions();
- return nullptr;
-}
-
void CommandObjectProxy::HandleCompletion(CompletionRequest &request) {
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
@@ -373,12 +389,15 @@ const char *CommandObjectProxy::GetRepeatCommand(Args &current_command_args,
return nullptr;
}
+llvm::StringRef CommandObjectProxy::GetUnsupportedError() {
+ return "command is not implemented";
+}
+
bool CommandObjectProxy::Execute(const char *args_string,
CommandReturnObject &result) {
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
return proxy_command->Execute(args_string, result);
- result.AppendError("command is not implemented");
- result.SetStatus(eReturnStatusFailed);
+ result.SetError(GetUnsupportedError());
return false;
}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp
index fcc8af6f915c..f306da3c8543 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "CommandObjectPlatform.h"
+#include "CommandOptionsProcessLaunch.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
@@ -392,7 +393,8 @@ public:
"or for a platform by name.",
"platform settings", 0),
m_options(),
- m_option_working_dir(LLDB_OPT_SET_1, false, "working-dir", 'w', 0,
+ m_option_working_dir(LLDB_OPT_SET_1, false, "working-dir", 'w',
+ CommandCompletions::eRemoteDiskDirectoryCompletion,
eArgTypePath,
"The working directory for the platform.") {
m_options.Append(&m_option_working_dir, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
@@ -485,6 +487,15 @@ public:
~CommandObjectPlatformFOpen() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex() == 0)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(),
+ CommandCompletions::eRemoteDiskFileCompletion, request, nullptr);
+ }
+
bool DoExecute(Args &args, CommandReturnObject &result) override {
PlatformSP platform_sp(
GetDebugger().GetPlatformList().GetSelectedPlatform());
@@ -817,6 +828,19 @@ public:
~CommandObjectPlatformGetFile() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex() == 0)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(),
+ CommandCompletions::eRemoteDiskFileCompletion, request, nullptr);
+ else if (request.GetCursorIndex() == 1)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ request, nullptr);
+ }
+
bool DoExecute(Args &args, CommandReturnObject &result) override {
// If the number of arguments is incorrect, issue an error message.
if (args.GetArgumentCount() != 2) {
@@ -882,6 +906,17 @@ public:
~CommandObjectPlatformGetSize() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex() != 0)
+ return;
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eRemoteDiskFileCompletion,
+ request, nullptr);
+ }
+
bool DoExecute(Args &args, CommandReturnObject &result) override {
// If the number of arguments is incorrect, issue an error message.
if (args.GetArgumentCount() != 1) {
@@ -927,6 +962,19 @@ public:
~CommandObjectPlatformPutFile() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex() == 0)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ request, nullptr);
+ else if (request.GetCursorIndex() == 1)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(),
+ CommandCompletions::eRemoteDiskFileCompletion, request, nullptr);
+ }
+
bool DoExecute(Args &args, CommandReturnObject &result) override {
const char *src = args.GetArgumentAtIndex(0);
const char *dst = args.GetArgumentAtIndex(1);
@@ -1036,7 +1084,7 @@ protected:
return result.Succeeded();
}
- ProcessLaunchCommandOptions m_options;
+ CommandOptionsProcessLaunch m_options;
};
// "platform process list"
@@ -1331,6 +1379,14 @@ public:
~CommandObjectPlatformProcessInfo() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eProcessIDCompletion,
+ request, nullptr);
+ }
+
protected:
bool DoExecute(Args &args, CommandReturnObject &result) override {
Target *target = GetDebugger().GetSelectedTarget().get();
@@ -1447,46 +1503,6 @@ public:
return llvm::makeArrayRef(g_platform_process_attach_options);
}
- void HandleOptionArgumentCompletion(
- CompletionRequest &request, OptionElementVector &opt_element_vector,
- int opt_element_index, CommandInterpreter &interpreter) override {
- int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
- int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
-
- // We are only completing the name option for now...
-
- // Are we in the name?
- if (GetDefinitions()[opt_defs_index].short_option != 'n')
- return;
-
- // 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 = nullptr;
- partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos);
-
- PlatformSP platform_sp(interpreter.GetPlatform(true));
- if (!platform_sp)
- return;
-
- ProcessInstanceInfoList process_infos;
- ProcessInstanceInfoMatch match_info;
- if (partial_name) {
- match_info.GetProcessInfo().GetExecutableFile().SetFile(
- partial_name, FileSpec::Style::native);
- match_info.SetNameMatchType(NameMatch::StartsWith);
- }
- platform_sp->FindProcesses(match_info, process_infos);
- const uint32_t num_matches = process_infos.size();
- if (num_matches == 0)
- return;
-
- for (uint32_t i = 0; i < num_matches; ++i) {
- request.AddCompletion(process_infos[i].GetNameAsStringRef());
- }
- return;
- }
-
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table[];
@@ -1596,6 +1612,16 @@ public:
else
m_timeout = std::chrono::seconds(timeout_sec);
break;
+ case 's': {
+ if (option_arg.empty()) {
+ error.SetErrorStringWithFormat(
+ "missing shell interpreter path for option -i|--interpreter.");
+ return error;
+ }
+
+ m_shell_interpreter = option_arg.str();
+ break;
+ }
default:
llvm_unreachable("Unimplemented option");
}
@@ -1606,10 +1632,12 @@ public:
void OptionParsingStarting(ExecutionContext *execution_context) override {
m_timeout.reset();
m_use_host_platform = false;
+ m_shell_interpreter.clear();
}
Timeout<std::micro> m_timeout = std::chrono::seconds(10);
bool m_use_host_platform;
+ std::string m_shell_interpreter;
};
CommandObjectPlatformShell(CommandInterpreter &interpreter)
@@ -1635,7 +1663,6 @@ public:
const bool is_alias = !raw_command_line.contains("platform");
OptionsWithRaw args(raw_command_line);
- const char *expr = args.GetRawPart().c_str();
if (args.HasArgs())
if (!ParseOptions(args.GetArgs(), result))
@@ -1647,6 +1674,8 @@ public:
return false;
}
+ llvm::StringRef cmd = args.GetRawPart();
+
PlatformSP platform_sp(
m_options.m_use_host_platform
? Platform::GetHostPlatform()
@@ -1657,7 +1686,8 @@ public:
std::string output;
int status = -1;
int signo = -1;
- error = (platform_sp->RunShellCommand(expr, working_dir, &status, &signo,
+ error = (platform_sp->RunShellCommand(m_options.m_shell_interpreter, cmd,
+ working_dir, &status, &signo,
&output, m_options.m_timeout));
if (!output.empty())
result.GetOutputStream().PutCString(output);
@@ -1706,6 +1736,16 @@ public:
~CommandObjectPlatformInstall() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex())
+ return;
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ request, nullptr);
+ }
+
bool DoExecute(Args &args, CommandReturnObject &result) override {
if (args.GetArgumentCount() != 2) {
result.AppendError("platform target-install takes two arguments");
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp
index f86779d85b5f..35835f638557 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "CommandObjectProcess.h"
+#include "CommandOptionsProcessLaunch.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointSite.h"
@@ -48,19 +49,19 @@ protected:
state = process->GetState();
if (process->IsAlive() && state != eStateConnected) {
- char message[1024];
+ std::string message;
if (process->GetState() == eStateAttaching)
- ::snprintf(message, sizeof(message),
- "There is a pending attach, abort it and %s?",
- m_new_process_action.c_str());
+ message =
+ llvm::formatv("There is a pending attach, abort it and {0}?",
+ m_new_process_action);
else if (process->GetShouldDetach())
- ::snprintf(message, sizeof(message),
- "There is a running process, detach from it and %s?",
- m_new_process_action.c_str());
+ message = llvm::formatv(
+ "There is a running process, detach from it and {0}?",
+ m_new_process_action);
else
- ::snprintf(message, sizeof(message),
- "There is a running process, kill it and %s?",
- m_new_process_action.c_str());
+ message =
+ llvm::formatv("There is a running process, kill it and {0}?",
+ m_new_process_action);
if (!m_interpreter.Confirm(message, true)) {
result.SetStatus(eReturnStatusFailed);
@@ -184,6 +185,9 @@ protected:
else
m_options.launch_info.GetFlags().Clear(eLaunchFlagDisableASLR);
+ if (target->GetInheritTCC())
+ m_options.launch_info.GetFlags().Set(eLaunchFlagInheritTCCFromParent);
+
if (target->GetDetachOnError())
m_options.launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
@@ -248,7 +252,7 @@ protected:
return result.Succeeded();
}
- ProcessLaunchCommandOptions m_options;
+ CommandOptionsProcessLaunch m_options;
};
#define LLDB_OPTIONS_process_attach
@@ -317,49 +321,6 @@ public:
return llvm::makeArrayRef(g_process_attach_options);
}
- void HandleOptionArgumentCompletion(
- CompletionRequest &request, OptionElementVector &opt_element_vector,
- int opt_element_index, CommandInterpreter &interpreter) override {
- int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
- int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
-
- switch (GetDefinitions()[opt_defs_index].short_option) {
- case 'n': {
- // 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 = nullptr;
- partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos);
-
- PlatformSP platform_sp(interpreter.GetPlatform(true));
- if (!platform_sp)
- return;
- ProcessInstanceInfoList process_infos;
- ProcessInstanceInfoMatch match_info;
- if (partial_name) {
- match_info.GetProcessInfo().GetExecutableFile().SetFile(
- partial_name, FileSpec::Style::native);
- match_info.SetNameMatchType(NameMatch::StartsWith);
- }
- platform_sp->FindProcesses(match_info, process_infos);
- const size_t num_matches = process_infos.size();
- if (num_matches == 0)
- return;
- for (size_t i = 0; i < num_matches; ++i) {
- request.AddCompletion(process_infos[i].GetNameAsStringRef());
- }
- } break;
-
- case 'P':
- CommandCompletions::InvokeCommonCompletionCallbacks(
- interpreter, CommandCompletions::eProcessPluginCompletion, request,
- nullptr);
- break;
- }
- }
-
- // Instance variables to hold the values for command options.
-
ProcessAttachInfo attach_info;
};
@@ -404,7 +365,6 @@ protected:
result.AppendError(error.AsCString("Error creating target"));
return false;
}
- GetDebugger().GetTargetList().SetSelectedTarget(target);
}
// Record the old executable module, we want to issue a warning if the
@@ -920,6 +880,17 @@ public:
~CommandObjectProcessLoad() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (!m_exe_ctx.HasProcessScope())
+ return;
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ request, nullptr);
+ }
+
Options *GetOptions() override { return &m_options; }
protected:
@@ -985,6 +956,24 @@ public:
~CommandObjectProcessUnload() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+
+ if (request.GetCursorIndex() || !m_exe_ctx.HasProcessScope())
+ return;
+
+ Process *process = m_exe_ctx.GetProcessPtr();
+
+ const std::vector<lldb::addr_t> &tokens = process->GetImageTokens();
+ const size_t token_num = tokens.size();
+ for (size_t i = 0; i < token_num; ++i) {
+ if (tokens[i] == LLDB_INVALID_IMAGE_TOKEN)
+ continue;
+ request.TryCompleteCurrentArg(std::to_string(i));
+ }
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Process *process = m_exe_ctx.GetProcessPtr();
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp
index d0c7bbd3abf8..d4d15bea9a8e 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp
@@ -103,5 +103,9 @@ bool CommandObjectQuit::DoExecute(Args &command, CommandReturnObject &result) {
CommandInterpreter::eBroadcastBitQuitCommandReceived;
m_interpreter.BroadcastEvent(event_type);
result.SetStatus(eReturnStatusQuit);
+
+ if (m_interpreter.GetSaveSessionOnQuit())
+ m_interpreter.SaveTranscript(result);
+
return true;
}
diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandObjectRegexCommand.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp
index 5a0265e58c5c..1bf29d3c047b 100644
--- a/contrib/llvm-project/lldb/source/Interpreter/CommandObjectRegexCommand.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp
@@ -6,8 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Interpreter/CommandObjectRegexCommand.h"
-
+#include "CommandObjectRegexCommand.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -17,7 +16,7 @@ using namespace lldb_private;
// CommandObjectRegexCommand constructor
CommandObjectRegexCommand::CommandObjectRegexCommand(
CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help,
- llvm::StringRef syntax, uint32_t max_matches, uint32_t completion_type_mask,
+ llvm::StringRef syntax, uint32_t max_matches, uint32_t completion_type_mask,
bool is_removable)
: CommandObjectRaw(interpreter, name, help, syntax),
m_max_matches(max_matches), m_completion_type_mask(completion_type_mask),
@@ -69,14 +68,13 @@ bool CommandObjectRegexCommand::DoExecute(llvm::StringRef command,
return false;
}
-bool CommandObjectRegexCommand::AddRegexCommand(const char *re_cstr,
- const char *command_cstr) {
+bool CommandObjectRegexCommand::AddRegexCommand(llvm::StringRef re_cstr,
+ llvm::StringRef command_cstr) {
m_entries.resize(m_entries.size() + 1);
// Only add the regular expression if it compiles
- m_entries.back().regex =
- RegularExpression(llvm::StringRef::withNullAsEmpty(re_cstr));
+ m_entries.back().regex = RegularExpression(re_cstr);
if (m_entries.back().regex.IsValid()) {
- m_entries.back().command.assign(command_cstr);
+ m_entries.back().command = command_cstr.str();
return true;
}
// The regex didn't compile...
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.h
index 01d7c6d118d4..2f65c2cd815d 100644
--- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.h
@@ -21,16 +21,16 @@ namespace lldb_private {
class CommandObjectRegexCommand : public CommandObjectRaw {
public:
- CommandObjectRegexCommand(CommandInterpreter &interpreter, llvm::StringRef name,
- llvm::StringRef help, llvm::StringRef syntax,
- uint32_t max_matches, uint32_t completion_type_mask,
- bool is_removable);
+ CommandObjectRegexCommand(CommandInterpreter &interpreter,
+ llvm::StringRef name, llvm::StringRef help,
+ llvm::StringRef syntax, uint32_t max_matches,
+ uint32_t completion_type_mask, bool is_removable);
~CommandObjectRegexCommand() override;
bool IsRemovable() const override { return m_is_removable; }
- bool AddRegexCommand(const char *re_cstr, const char *command_cstr);
+ bool AddRegexCommand(llvm::StringRef re_cstr, llvm::StringRef command_cstr);
bool HasRegexEntries() const { return !m_entries.empty(); }
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp
index 104130b70b2b..55f34c05d11d 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp
@@ -27,10 +27,12 @@ using namespace lldb_private::repro;
enum ReproducerProvider {
eReproducerProviderCommands,
eReproducerProviderFiles,
+ eReproducerProviderSymbolFiles,
eReproducerProviderGDB,
eReproducerProviderProcessInfo,
eReproducerProviderVersion,
eReproducerProviderWorkingDirectory,
+ eReproducerProviderHomeDirectory,
eReproducerProviderNone
};
@@ -46,6 +48,11 @@ static constexpr OptionEnumValueElement g_reproducer_provider_type[] = {
"Files",
},
{
+ eReproducerProviderSymbolFiles,
+ "symbol-files",
+ "Symbol Files",
+ },
+ {
eReproducerProviderGDB,
"gdb",
"GDB Remote Packets",
@@ -66,6 +73,11 @@ static constexpr OptionEnumValueElement g_reproducer_provider_type[] = {
"Working Directory",
},
{
+ eReproducerProviderHomeDirectory,
+ "home",
+ "Home Directory",
+ },
+ {
eReproducerProviderNone,
"none",
"None",
@@ -104,6 +116,9 @@ static constexpr OptionEnumValues ReproducerSignalType() {
#define LLDB_OPTIONS_reproducer_xcrash
#include "CommandOptions.inc"
+#define LLDB_OPTIONS_reproducer_verify
+#include "CommandOptions.inc"
+
template <typename T>
llvm::Expected<T> static ReadFromYAML(StringRef filename) {
auto error_or_file = MemoryBuffer::getFile(filename);
@@ -122,6 +137,38 @@ llvm::Expected<T> static ReadFromYAML(StringRef filename) {
return t;
}
+static void SetError(CommandReturnObject &result, Error err) {
+ result.GetErrorStream().Printf("error: %s\n",
+ toString(std::move(err)).c_str());
+ result.SetStatus(eReturnStatusFailed);
+}
+
+/// Create a loader from the given path if specified. Otherwise use the current
+/// loader used for replay.
+static Loader *
+GetLoaderFromPathOrCurrent(llvm::Optional<Loader> &loader_storage,
+ CommandReturnObject &result,
+ FileSpec reproducer_path) {
+ if (reproducer_path) {
+ loader_storage.emplace(reproducer_path);
+ Loader *loader = &(*loader_storage);
+ if (Error err = loader->LoadIndex()) {
+ // This is a hard error and will set the result to eReturnStatusFailed.
+ SetError(result, std::move(err));
+ return nullptr;
+ }
+ return loader;
+ }
+
+ if (Loader *loader = Reproducer::Instance().GetLoader())
+ return loader;
+
+ // This is a soft error because this is expected to fail during capture.
+ result.SetError("Not specifying a reproducer is only support during replay.");
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return nullptr;
+}
+
class CommandObjectReproducerGenerate : public CommandObjectParsed {
public:
CommandObjectReproducerGenerate(CommandInterpreter &interpreter)
@@ -145,6 +192,10 @@ protected:
auto &r = Reproducer::Instance();
if (auto generator = r.GetGenerator()) {
generator->Keep();
+ if (llvm::Error e = repro::Finalize(r.GetReproducerPath())) {
+ SetError(result, std::move(e));
+ return result.Succeeded();
+ }
} else if (r.IsReplaying()) {
// Make this operation a NO-OP in replay mode.
result.SetStatus(eReturnStatusSuccessFinishNoResult);
@@ -300,12 +351,6 @@ protected:
}
};
-static void SetError(CommandReturnObject &result, Error err) {
- result.GetErrorStream().Printf("error: %s\n",
- toString(std::move(err)).c_str());
- result.SetStatus(eReturnStatusFailed);
-}
-
class CommandObjectReproducerDump : public CommandObjectParsed {
public:
CommandObjectReproducerDump(CommandInterpreter &interpreter)
@@ -370,29 +415,11 @@ protected:
return false;
}
- // If no reproducer path is specified, use the loader currently used for
- // replay. Otherwise create a new loader just for dumping.
llvm::Optional<Loader> loader_storage;
- Loader *loader = nullptr;
- if (!m_options.file) {
- loader = Reproducer::Instance().GetLoader();
- if (loader == nullptr) {
- result.SetError(
- "Not specifying a reproducer is only support during replay.");
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return false;
- }
- } else {
- loader_storage.emplace(m_options.file);
- loader = &(*loader_storage);
- if (Error err = loader->LoadIndex()) {
- SetError(result, std::move(err));
- return false;
- }
- }
-
- // If we get here we should have a valid loader.
- assert(loader);
+ Loader *loader =
+ GetLoaderFromPathOrCurrent(loader_storage, result, m_options.file);
+ if (!loader)
+ return false;
switch (m_options.provider) {
case eReproducerProviderFiles: {
@@ -421,6 +448,29 @@ protected:
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
}
+ case eReproducerProviderSymbolFiles: {
+ Expected<std::string> symbol_files =
+ loader->LoadBuffer<SymbolFileProvider>();
+ if (!symbol_files) {
+ SetError(result, symbol_files.takeError());
+ return false;
+ }
+
+ std::vector<SymbolFileProvider::Entry> entries;
+ llvm::yaml::Input yin(*symbol_files);
+ yin >> entries;
+
+ for (const auto &entry : entries) {
+ result.AppendMessageWithFormat("- uuid: %s\n",
+ entry.uuid.c_str());
+ result.AppendMessageWithFormat(" module path: %s\n",
+ entry.module_path.c_str());
+ result.AppendMessageWithFormat(" symbol path: %s\n",
+ entry.symbol_path.c_str());
+ }
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
case eReproducerProviderVersion: {
Expected<std::string> version = loader->LoadBuffer<VersionProvider>();
if (!version) {
@@ -433,7 +483,7 @@ protected:
}
case eReproducerProviderWorkingDirectory: {
Expected<std::string> cwd =
- loader->LoadBuffer<WorkingDirectoryProvider>();
+ repro::GetDirectoryFrom<WorkingDirectoryProvider>(loader);
if (!cwd) {
SetError(result, cwd.takeError());
return false;
@@ -442,6 +492,17 @@ protected:
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
}
+ case eReproducerProviderHomeDirectory: {
+ Expected<std::string> home =
+ repro::GetDirectoryFrom<HomeDirectoryProvider>(loader);
+ if (!home) {
+ SetError(result, home.takeError());
+ return false;
+ }
+ result.AppendMessage(*home);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
case eReproducerProviderCommands: {
std::unique_ptr<repro::MultiLoader<repro::CommandProvider>> multi_loader =
repro::MultiLoader<repro::CommandProvider>::Create(loader);
@@ -537,6 +598,101 @@ private:
CommandOptions m_options;
};
+class CommandObjectReproducerVerify : public CommandObjectParsed {
+public:
+ CommandObjectReproducerVerify(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "reproducer verify",
+ "Verify the contents of a reproducer. "
+ "If no reproducer is specified during replay, it "
+ "verifies the content of the current reproducer.",
+ nullptr) {}
+
+ ~CommandObjectReproducerVerify() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), file() {}
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'f':
+ file.SetFile(option_arg, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(file);
+ break;
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ file.Clear();
+ }
+
+ ArrayRef<OptionDefinition> GetDefinitions() override {
+ return makeArrayRef(g_reproducer_verify_options);
+ }
+
+ FileSpec file;
+ };
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (!command.empty()) {
+ result.AppendErrorWithFormat("'%s' takes no arguments",
+ m_cmd_name.c_str());
+ return false;
+ }
+
+ llvm::Optional<Loader> loader_storage;
+ Loader *loader =
+ GetLoaderFromPathOrCurrent(loader_storage, result, m_options.file);
+ if (!loader)
+ return false;
+
+ bool errors = false;
+ auto error_callback = [&](llvm::StringRef error) {
+ errors = true;
+ result.AppendError(error);
+ };
+
+ bool warnings = false;
+ auto warning_callback = [&](llvm::StringRef warning) {
+ warnings = true;
+ result.AppendWarning(warning);
+ };
+
+ auto note_callback = [&](llvm::StringRef warning) {
+ result.AppendMessage(warning);
+ };
+
+ Verifier verifier(loader);
+ verifier.Verify(error_callback, warning_callback, note_callback);
+
+ if (warnings || errors) {
+ result.AppendMessage("reproducer verification failed");
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ result.AppendMessage("reproducer verification succeeded");
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+
+ return result.Succeeded();
+ }
+
+private:
+ CommandOptions m_options;
+};
+
CommandObjectReproducer::CommandObjectReproducer(
CommandInterpreter &interpreter)
: CommandObjectMultiword(
@@ -559,6 +715,8 @@ CommandObjectReproducer::CommandObjectReproducer(
new CommandObjectReproducerStatus(interpreter)));
LoadSubCommand("dump",
CommandObjectSP(new CommandObjectReproducerDump(interpreter)));
+ LoadSubCommand("verify", CommandObjectSP(
+ new CommandObjectReproducerVerify(interpreter)));
LoadSubCommand("xcrash", CommandObjectSP(
new CommandObjectReproducerXCrash(interpreter)));
}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.cpp
new file mode 100644
index 000000000000..9dadf11ebfc8
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.cpp
@@ -0,0 +1,138 @@
+//===-- CommandObjectScript.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectScript.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/DataFormatters/DataVisualization.h"
+#include "lldb/Host/Config.h"
+#include "lldb/Host/OptionParser.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Utility/Args.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+static constexpr OptionEnumValueElement g_script_option_enumeration[] = {
+ {
+ eScriptLanguagePython,
+ "python",
+ "Python",
+ },
+ {
+ eScriptLanguageLua,
+ "lua",
+ "Lua",
+ },
+ {
+ eScriptLanguageNone,
+ "default",
+ "The default scripting language.",
+ },
+};
+
+static constexpr OptionEnumValues ScriptOptionEnum() {
+ return OptionEnumValues(g_script_option_enumeration);
+}
+
+#define LLDB_OPTIONS_script
+#include "CommandOptions.inc"
+
+Status CommandObjectScript::CommandOptions::SetOptionValue(
+ uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'l':
+ language = (lldb::ScriptLanguage)OptionArgParser::ToOptionEnum(
+ option_arg, GetDefinitions()[option_idx].enum_values,
+ eScriptLanguageNone, error);
+ if (!error.Success())
+ error.SetErrorStringWithFormat("unrecognized value for language '%s'",
+ option_arg.str().c_str());
+ break;
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+
+ return error;
+}
+
+void CommandObjectScript::CommandOptions::OptionParsingStarting(
+ ExecutionContext *execution_context) {
+ language = lldb::eScriptLanguageNone;
+}
+
+llvm::ArrayRef<OptionDefinition>
+CommandObjectScript::CommandOptions::GetDefinitions() {
+ return llvm::makeArrayRef(g_script_options);
+}
+
+CommandObjectScript::CommandObjectScript(CommandInterpreter &interpreter)
+ : CommandObjectRaw(
+ interpreter, "script",
+ "Invoke the script interpreter with provided code and display any "
+ "results. Start the interactive interpreter if no code is supplied.",
+ "script [--language <scripting-language> --] [<script-code>]") {}
+
+CommandObjectScript::~CommandObjectScript() {}
+
+bool CommandObjectScript::DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) {
+ // Try parsing the language option but when the command contains a raw part
+ // separated by the -- delimiter.
+ OptionsWithRaw raw_args(command);
+ if (raw_args.HasArgs()) {
+ if (!ParseOptions(raw_args.GetArgs(), result))
+ return false;
+ command = raw_args.GetRawPart();
+ }
+
+ lldb::ScriptLanguage language =
+ (m_options.language == lldb::eScriptLanguageNone)
+ ? m_interpreter.GetDebugger().GetScriptLanguage()
+ : m_options.language;
+
+ if (language == lldb::eScriptLanguageNone) {
+ result.AppendError(
+ "the script-lang setting is set to none - scripting not available");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ ScriptInterpreter *script_interpreter =
+ GetDebugger().GetScriptInterpreter(true, language);
+
+ if (script_interpreter == nullptr) {
+ result.AppendError("no script interpreter");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // Script might change Python code we use for formatting. Make sure we keep
+ // up to date with it.
+ DataVisualization::ForceUpdate();
+
+ if (command.empty()) {
+ script_interpreter->ExecuteInterpreterLoop();
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
+ }
+
+ // We can do better when reporting the status of one-liner script execution.
+ if (script_interpreter->ExecuteOneLine(command, &result))
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ else
+ result.SetStatus(eReturnStatusFailed);
+
+ return result.Succeeded();
+}
diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandObjectScript.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.h
index a5f659995de3..b9fee7124818 100644
--- a/contrib/llvm-project/lldb/source/Interpreter/CommandObjectScript.h
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.h
@@ -13,17 +13,28 @@
namespace lldb_private {
-// CommandObjectScript
-
class CommandObjectScript : public CommandObjectRaw {
public:
- CommandObjectScript(CommandInterpreter &interpreter,
- lldb::ScriptLanguage script_lang);
-
+ CommandObjectScript(CommandInterpreter &interpreter);
~CommandObjectScript() override;
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+ ~CommandOptions() override = default;
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override;
+ void OptionParsingStarting(ExecutionContext *execution_context) override;
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+ lldb::ScriptLanguage language = lldb::eScriptLanguageNone;
+ };
protected:
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override;
+
+private:
+ CommandOptions m_options;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.cpp
new file mode 100644
index 000000000000..c2cdfa29a3f6
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.cpp
@@ -0,0 +1,208 @@
+#include "CommandObjectSession.h"
+#include "lldb/Host/OptionParser.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Interpreter/OptionValue.h"
+#include "lldb/Interpreter/OptionValueBoolean.h"
+#include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Interpreter/OptionValueUInt64.h"
+#include "lldb/Interpreter/Options.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+class CommandObjectSessionSave : public CommandObjectParsed {
+public:
+ CommandObjectSessionSave(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "session save",
+ "Save the current session transcripts to a file.\n"
+ "If no file if specified, transcripts will be "
+ "saved to a temporary file.",
+ "session save [file]") {
+ CommandArgumentEntry arg1;
+ arg1.emplace_back(eArgTypePath, eArgRepeatOptional);
+ m_arguments.push_back(arg1);
+ }
+
+ ~CommandObjectSessionSave() override = default;
+
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ request, nullptr);
+ }
+
+protected:
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ llvm::StringRef file_path;
+
+ if (!args.empty())
+ file_path = args[0].ref();
+
+ if (m_interpreter.SaveTranscript(result, file_path.str()))
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ else
+ result.SetStatus(eReturnStatusFailed);
+ return result.Succeeded();
+ }
+};
+
+#define LLDB_OPTIONS_history
+#include "CommandOptions.inc"
+
+class CommandObjectSessionHistory : public CommandObjectParsed {
+public:
+ CommandObjectSessionHistory(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "session history",
+ "Dump the history of commands in this session.\n"
+ "Commands in the history list can be run again "
+ "using \"!<INDEX>\". \"!-<OFFSET>\" will re-run "
+ "the command that is <OFFSET> commands from the end"
+ " of the list (counting the current command).",
+ nullptr),
+ m_options() {}
+
+ ~CommandObjectSessionHistory() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+protected:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_start_idx(0), m_stop_idx(0), m_count(0), m_clear(false) {
+ }
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'c':
+ error = m_count.SetValueFromString(option_arg, eVarSetOperationAssign);
+ break;
+ case 's':
+ if (option_arg == "end") {
+ m_start_idx.SetCurrentValue(UINT64_MAX);
+ m_start_idx.SetOptionWasSet();
+ } else
+ error = m_start_idx.SetValueFromString(option_arg,
+ eVarSetOperationAssign);
+ break;
+ case 'e':
+ error =
+ m_stop_idx.SetValueFromString(option_arg, eVarSetOperationAssign);
+ break;
+ case 'C':
+ m_clear.SetCurrentValue(true);
+ m_clear.SetOptionWasSet();
+ break;
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_start_idx.Clear();
+ m_stop_idx.Clear();
+ m_count.Clear();
+ m_clear.Clear();
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_history_options);
+ }
+
+ // Instance variables to hold the values for command options.
+
+ OptionValueUInt64 m_start_idx;
+ OptionValueUInt64 m_stop_idx;
+ OptionValueUInt64 m_count;
+ OptionValueBoolean m_clear;
+ };
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (m_options.m_clear.GetCurrentValue() &&
+ m_options.m_clear.OptionWasSet()) {
+ m_interpreter.GetCommandHistory().Clear();
+ result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
+ } else {
+ if (m_options.m_start_idx.OptionWasSet() &&
+ m_options.m_stop_idx.OptionWasSet() &&
+ m_options.m_count.OptionWasSet()) {
+ result.AppendError("--count, --start-index and --end-index cannot be "
+ "all specified in the same invocation");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ } else {
+ std::pair<bool, uint64_t> start_idx(
+ m_options.m_start_idx.OptionWasSet(),
+ m_options.m_start_idx.GetCurrentValue());
+ std::pair<bool, uint64_t> stop_idx(
+ m_options.m_stop_idx.OptionWasSet(),
+ m_options.m_stop_idx.GetCurrentValue());
+ std::pair<bool, uint64_t> count(m_options.m_count.OptionWasSet(),
+ m_options.m_count.GetCurrentValue());
+
+ const CommandHistory &history(m_interpreter.GetCommandHistory());
+
+ if (start_idx.first && start_idx.second == UINT64_MAX) {
+ if (count.first) {
+ start_idx.second = history.GetSize() - count.second;
+ stop_idx.second = history.GetSize() - 1;
+ } else if (stop_idx.first) {
+ start_idx.second = stop_idx.second;
+ stop_idx.second = history.GetSize() - 1;
+ } else {
+ start_idx.second = 0;
+ stop_idx.second = history.GetSize() - 1;
+ }
+ } else {
+ if (!start_idx.first && !stop_idx.first && !count.first) {
+ start_idx.second = 0;
+ stop_idx.second = history.GetSize() - 1;
+ } else if (start_idx.first) {
+ if (count.first) {
+ stop_idx.second = start_idx.second + count.second - 1;
+ } else if (!stop_idx.first) {
+ stop_idx.second = history.GetSize() - 1;
+ }
+ } else if (stop_idx.first) {
+ if (count.first) {
+ if (stop_idx.second >= count.second)
+ start_idx.second = stop_idx.second - count.second + 1;
+ else
+ start_idx.second = 0;
+ }
+ } else /* if (count.first) */
+ {
+ start_idx.second = 0;
+ stop_idx.second = count.second - 1;
+ }
+ }
+ history.Dump(result.GetOutputStream(), start_idx.second,
+ stop_idx.second);
+ }
+ }
+ return result.Succeeded();
+ }
+
+ CommandOptions m_options;
+};
+
+CommandObjectSession::CommandObjectSession(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "session",
+ "Commands controlling LLDB session.",
+ "session <subcommand> [<command-options>]") {
+ LoadSubCommand("save",
+ CommandObjectSP(new CommandObjectSessionSave(interpreter)));
+ LoadSubCommand("history",
+ CommandObjectSP(new CommandObjectSessionHistory(interpreter)));
+}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.h
new file mode 100644
index 000000000000..0af0e279f47e
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.h
@@ -0,0 +1,23 @@
+//===-- CommandObjectSession.h ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTSESSION_H
+#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTSESSION_H
+
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+
+namespace lldb_private {
+
+class CommandObjectSession : public CommandObjectMultiword {
+public:
+ CommandObjectSession(CommandInterpreter &interpreter);
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTSESSION_H
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp
index 1ccfd3a5166f..8fff22a06366 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp
@@ -16,6 +16,7 @@
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Interpreter/OptionValueFileColonLine.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
@@ -667,6 +668,22 @@ class CommandObjectSourceList : public CommandObjectParsed {
case 'r':
reverse = true;
break;
+ case 'y':
+ {
+ OptionValueFileColonLine value;
+ Status fcl_err = value.SetValueFromString(option_arg);
+ if (!fcl_err.Success()) {
+ error.SetErrorStringWithFormat(
+ "Invalid value for file:line specifier: %s",
+ fcl_err.AsCString());
+ } else {
+ file_name = value.GetFileSpec().GetPath();
+ start_line = value.GetLineNumber();
+ // I don't see anything useful to do with a column number, but I don't
+ // want to complain since someone may well have cut and pasted a
+ // listing from somewhere that included a column.
+ }
+ } break;
default:
llvm_unreachable("Unimplemented option");
}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp
index 7bb71f4d518c..1cb21384fd2a 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp
@@ -23,6 +23,8 @@
#include "lldb/Interpreter/OptionGroupBoolean.h"
#include "lldb/Interpreter/OptionGroupFile.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
+#include "lldb/Interpreter/OptionGroupPlatform.h"
+#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
#include "lldb/Interpreter/OptionGroupString.h"
#include "lldb/Interpreter/OptionGroupUInt64.h"
#include "lldb/Interpreter/OptionGroupUUID.h"
@@ -48,6 +50,7 @@
#include "lldb/Utility/State.h"
#include "lldb/Utility/Timer.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatAdapters.h"
@@ -206,8 +209,6 @@ private:
#pragma mark CommandObjectTargetCreate
-// "target create"
-
class CommandObjectTargetCreate : public CommandObjectParsed {
public:
CommandObjectTargetCreate(CommandInterpreter &interpreter)
@@ -216,11 +217,9 @@ public:
"Create a target using the argument as the main executable.",
nullptr),
m_option_group(), m_arch_option(),
+ m_platform_options(true), // Include the --platform option.
m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
"Fullpath to a core file to use for this target."),
- m_platform_path(LLDB_OPT_SET_1, false, "platform-path", 'P', 0,
- eArgTypePath,
- "Path to the remote file to use for this target."),
m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
eArgTypeFilename,
"Fullpath to a stand alone debug "
@@ -245,8 +244,8 @@ public:
m_arguments.push_back(arg);
m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_platform_options, LLDB_OPT_SET_ALL, 1);
m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append(&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
@@ -300,8 +299,7 @@ protected:
}
const char *file_path = command.GetArgumentAtIndex(0);
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "(lldb) target create '%s'", file_path);
+ LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path);
FileSpec file_spec;
if (file_path) {
@@ -317,124 +315,127 @@ protected:
llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
Status error(debugger.GetTargetList().CreateTarget(
debugger, file_path, arch_cstr,
- m_add_dependents.m_load_dependent_files, nullptr, target_sp));
+ m_add_dependents.m_load_dependent_files, &m_platform_options,
+ target_sp));
- if (target_sp) {
- // Only get the platform after we create the target because we might
- // have switched platforms depending on what the arguments were to
- // CreateTarget() we can't rely on the selected platform.
-
- PlatformSP platform_sp = target_sp->GetPlatform();
-
- if (remote_file) {
- if (platform_sp) {
- // I have a remote file.. two possible cases
- if (file_spec && FileSystem::Instance().Exists(file_spec)) {
- // if the remote file does not exist, push it there
- if (!platform_sp->GetFileExists(remote_file)) {
- Status err = platform_sp->PutFile(file_spec, remote_file);
- if (err.Fail()) {
- result.AppendError(err.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- } else {
- // there is no local file and we need one
- // in order to make the remote ---> local transfer we need a
- // platform
- // TODO: if the user has passed in a --platform argument, use it
- // to fetch the right platform
- if (!platform_sp) {
- result.AppendError(
- "unable to perform remote debugging without a platform");
+ if (!target_sp) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ auto on_error = llvm::make_scope_exit(
+ [&target_list = debugger.GetTargetList(), &target_sp]() {
+ target_list.DeleteTarget(target_sp);
+ });
+
+ // Only get the platform after we create the target because we might
+ // have switched platforms depending on what the arguments were to
+ // CreateTarget() we can't rely on the selected platform.
+
+ PlatformSP platform_sp = target_sp->GetPlatform();
+
+ if (remote_file) {
+ if (platform_sp) {
+ // I have a remote file.. two possible cases
+ if (file_spec && FileSystem::Instance().Exists(file_spec)) {
+ // if the remote file does not exist, push it there
+ if (!platform_sp->GetFileExists(remote_file)) {
+ Status err = platform_sp->PutFile(file_spec, remote_file);
+ if (err.Fail()) {
+ result.AppendError(err.AsCString());
result.SetStatus(eReturnStatusFailed);
return false;
}
- if (file_path) {
- // copy the remote file to the local file
- Status err = platform_sp->GetFile(remote_file, file_spec);
- if (err.Fail()) {
- result.AppendError(err.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- } else {
- // make up a local file
- result.AppendError("remote --> local transfer without local "
- "path is not implemented yet");
+ }
+ } else {
+ // there is no local file and we need one
+ // in order to make the remote ---> local transfer we need a
+ // platform
+ // TODO: if the user has passed in a --platform argument, use it
+ // to fetch the right platform
+ if (file_path) {
+ // copy the remote file to the local file
+ Status err = platform_sp->GetFile(remote_file, file_spec);
+ if (err.Fail()) {
+ result.AppendError(err.AsCString());
result.SetStatus(eReturnStatusFailed);
return false;
}
+ } else {
+ // make up a local file
+ result.AppendError("remote --> local transfer without local "
+ "path is not implemented yet");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- } else {
- result.AppendError("no platform found for target");
- result.SetStatus(eReturnStatusFailed);
- return false;
}
+ } else {
+ result.AppendError("no platform found for target");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ }
- if (symfile || remote_file) {
- ModuleSP module_sp(target_sp->GetExecutableModule());
- if (module_sp) {
- if (symfile)
- module_sp->SetSymbolFileFileSpec(symfile);
- if (remote_file) {
- std::string remote_path = remote_file.GetPath();
- target_sp->SetArg0(remote_path.c_str());
- module_sp->SetPlatformFileSpec(remote_file);
- }
+ if (symfile || remote_file) {
+ ModuleSP module_sp(target_sp->GetExecutableModule());
+ if (module_sp) {
+ if (symfile)
+ module_sp->SetSymbolFileFileSpec(symfile);
+ if (remote_file) {
+ std::string remote_path = remote_file.GetPath();
+ target_sp->SetArg0(remote_path.c_str());
+ module_sp->SetPlatformFileSpec(remote_file);
}
}
+ }
- debugger.GetTargetList().SetSelectedTarget(target_sp.get());
- if (must_set_platform_path) {
- ModuleSpec main_module_spec(file_spec);
- ModuleSP module_sp =
- target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
- if (module_sp)
- module_sp->SetPlatformFileSpec(remote_file);
- }
+ if (must_set_platform_path) {
+ ModuleSpec main_module_spec(file_spec);
+ ModuleSP module_sp =
+ target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
+ if (module_sp)
+ module_sp->SetPlatformFileSpec(remote_file);
+ }
- if (core_file) {
- FileSpec core_file_dir;
- core_file_dir.GetDirectory() = core_file.GetDirectory();
- target_sp->AppendExecutableSearchPaths(core_file_dir);
+ if (core_file) {
+ FileSpec core_file_dir;
+ core_file_dir.GetDirectory() = core_file.GetDirectory();
+ target_sp->AppendExecutableSearchPaths(core_file_dir);
- ProcessSP process_sp(target_sp->CreateProcess(
- GetDebugger().GetListener(), llvm::StringRef(), &core_file));
+ ProcessSP process_sp(target_sp->CreateProcess(
+ GetDebugger().GetListener(), llvm::StringRef(), &core_file, false));
- if (process_sp) {
- // Seems weird that we Launch a core file, but that is what we
- // do!
- error = process_sp->LoadCore();
+ if (process_sp) {
+ // Seems weird that we Launch a core file, but that is what we
+ // do!
+ error = process_sp->LoadCore();
- if (error.Fail()) {
- result.AppendError(
- error.AsCString("can't find plug-in for core file"));
- result.SetStatus(eReturnStatusFailed);
- return false;
- } else {
- result.AppendMessageWithFormatv("Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
- target_sp->GetArchitecture().GetArchitectureName());
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
- } else {
- result.AppendErrorWithFormatv(
- "Unable to find process plug-in for core file '{0}'\n",
- core_file.GetPath());
+ if (error.Fail()) {
+ result.AppendError(
+ error.AsCString("can't find plug-in for core file"));
result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ result.AppendMessageWithFormatv(
+ "Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
+ target_sp->GetArchitecture().GetArchitectureName());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ on_error.release();
}
} else {
- result.AppendMessageWithFormat(
- "Current executable set to '%s' (%s).\n",
- file_spec.GetPath().c_str(),
- target_sp->GetArchitecture().GetArchitectureName());
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ result.AppendErrorWithFormatv(
+ "Unable to find process plug-in for core file '{0}'\n",
+ core_file.GetPath());
+ result.SetStatus(eReturnStatusFailed);
}
} else {
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
+ result.AppendMessageWithFormat(
+ "Current executable set to '%s' (%s).\n",
+ file_spec.GetPath().c_str(),
+ target_sp->GetArchitecture().GetArchitectureName());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ on_error.release();
}
} else {
result.AppendErrorWithFormat("'%s' takes exactly one executable path "
@@ -442,14 +443,15 @@ protected:
m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
}
+
return result.Succeeded();
}
private:
OptionGroupOptions m_option_group;
OptionGroupArchitecture m_arch_option;
+ OptionGroupPlatform m_platform_options;
OptionGroupFile m_core_file;
- OptionGroupFile m_platform_path;
OptionGroupFile m_symbol_file;
OptionGroupFile m_remote_file;
OptionGroupDependents m_add_dependents;
@@ -457,8 +459,6 @@ private:
#pragma mark CommandObjectTargetList
-// "target list"
-
class CommandObjectTargetList : public CommandObjectParsed {
public:
CommandObjectTargetList(CommandInterpreter &interpreter)
@@ -490,8 +490,6 @@ protected:
#pragma mark CommandObjectTargetSelect
-// "target select"
-
class CommandObjectTargetSelect : public CommandObjectParsed {
public:
CommandObjectTargetSelect(CommandInterpreter &interpreter)
@@ -511,18 +509,11 @@ protected:
TargetList &target_list = GetDebugger().GetTargetList();
const uint32_t num_targets = target_list.GetNumTargets();
if (target_idx < num_targets) {
- TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
- if (target_sp) {
- Stream &strm = result.GetOutputStream();
- target_list.SetSelectedTarget(target_sp.get());
- bool show_stopped_process_status = false;
- DumpTargetList(target_list, show_stopped_process_status, strm);
- result.SetStatus(eReturnStatusSuccessFinishResult);
- } else {
- result.AppendErrorWithFormat("target #%u is NULL in target list\n",
- target_idx);
- result.SetStatus(eReturnStatusFailed);
- }
+ target_list.SetSelectedTarget(target_idx);
+ Stream &strm = result.GetOutputStream();
+ bool show_stopped_process_status = false;
+ DumpTargetList(target_list, show_stopped_process_status, strm);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
} else {
if (num_targets > 0) {
result.AppendErrorWithFormat(
@@ -551,8 +542,6 @@ protected:
#pragma mark CommandObjectTargetDelete
-// "target delete"
-
class CommandObjectTargetDelete : public CommandObjectParsed {
public:
CommandObjectTargetDelete(CommandInterpreter &interpreter)
@@ -697,8 +686,6 @@ protected:
#pragma mark CommandObjectTargetVariable
-// "target variable"
-
class CommandObjectTargetVariable : public CommandObjectParsed {
static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
@@ -917,6 +904,7 @@ protected:
CompileUnit *comp_unit = nullptr;
if (frame) {
SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
+ comp_unit = sc.comp_unit;
if (sc.comp_unit) {
const bool can_create = true;
VariableListSP comp_unit_varlist_sp(
@@ -1167,6 +1155,25 @@ public:
~CommandObjectTargetModulesSearchPathsInsert() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (!m_exe_ctx.HasTargetScope() || request.GetCursorIndex() != 0)
+ return;
+
+ Target *target = m_exe_ctx.GetTargetPtr();
+ const PathMappingList &list = target->GetImageSearchPathList();
+ const size_t num = list.GetSize();
+ ConstString old_path, new_path;
+ for (size_t i = 0; i < num; ++i) {
+ if (!list.GetPathsAtIndex(i, old_path, new_path))
+ break;
+ StreamString strm;
+ strm << old_path << " -> " << new_path;
+ request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
+ }
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Target *target = &GetSelectedTarget();
@@ -1392,31 +1399,30 @@ static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
}
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();
- if (objfile)
- objfile->Dump(&strm);
- else {
- strm.Format("No object file for module: {0:F}\n",
- module->GetFileSpec());
- }
+ if (num_modules == 0)
+ return 0;
+
+ size_t num_dumped = 0;
+ strm.Format("Dumping headers for {0} module(s).\n", num_modules);
+ strm.IndentMore();
+ for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
+ if (module_sp) {
+ if (num_dumped++ > 0) {
+ strm.EOL();
+ strm.EOL();
+ }
+ ObjectFile *objfile = module_sp->GetObjectFile();
+ if (objfile)
+ objfile->Dump(&strm);
+ else {
+ strm.Format("No object file for module: {0:F}\n",
+ module_sp->GetFileSpec());
}
}
- strm.IndentLess();
}
+ strm.IndentLess();
return num_dumped;
}
@@ -1624,7 +1630,8 @@ static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
return 0;
}
-static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
+static size_t LookupTypeInModule(Target *target,
+ CommandInterpreter &interpreter, Stream &strm,
Module *module, const char *name_cstr,
bool name_is_regex) {
TypeList type_list;
@@ -1652,7 +1659,7 @@ static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
// Resolve the clang type so that any forward references to types
// that haven't yet been parsed will get parsed.
type_sp->GetFullCompilerType();
- type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
+ type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
// Print all typedef chains
TypeSP typedef_type_sp(type_sp);
TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
@@ -1661,7 +1668,8 @@ static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
strm.Printf(" typedef '%s': ",
typedef_type_sp->GetName().GetCString());
typedefed_type_sp->GetFullCompilerType();
- typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
+ typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
+ target);
typedef_type_sp = typedefed_type_sp;
typedefed_type_sp = typedef_type_sp->GetTypedefType();
}
@@ -1671,9 +1679,9 @@ static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
return type_list.GetSize();
}
-static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
- Module &module, const char *name_cstr,
- bool name_is_regex) {
+static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
+ Stream &strm, Module &module,
+ const char *name_cstr, bool name_is_regex) {
TypeList type_list;
const uint32_t max_num_matches = UINT32_MAX;
bool name_is_fully_qualified = false;
@@ -1696,8 +1704,8 @@ static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
// Resolve the clang type so that any forward references to types that
// haven't yet been parsed will get parsed.
type_sp->GetFullCompilerType();
- type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
- // Print all typedef chains
+ type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
+ // Print all typedef chains.
TypeSP typedef_type_sp(type_sp);
TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
while (typedefed_type_sp) {
@@ -1705,7 +1713,8 @@ static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
strm.Printf(" typedef '%s': ",
typedef_type_sp->GetName().GetCString());
typedefed_type_sp->GetFullCompilerType();
- typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
+ typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
+ target);
typedef_type_sp = typedefed_type_sp;
typedefed_type_sp = typedef_type_sp->GetTypedefType();
}
@@ -2015,14 +2024,13 @@ protected:
if (command.GetArgumentCount() == 0) {
// Dump all sections for all modules images
- std::lock_guard<std::recursive_mutex> guard(
- target->GetImages().GetMutex());
- const size_t num_modules = target->GetImages().GetSize();
+ const ModuleList &module_list = target->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
+ const size_t num_modules = module_list.GetSize();
if (num_modules > 0) {
- result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
- " modules.\n",
- (uint64_t)num_modules);
- for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ result.GetOutputStream().Format(
+ "Dumping symbol table for {0} modules.\n", num_modules);
+ for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
if (num_dumped > 0) {
result.GetOutputStream().EOL();
result.GetOutputStream().EOL();
@@ -2030,10 +2038,9 @@ protected:
if (m_interpreter.WasInterrupted())
break;
num_dumped++;
- DumpModuleSymtab(
- m_interpreter, result.GetOutputStream(),
- target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
- m_options.m_sort_order, name_preference);
+ DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
+ module_sp.get(), m_options.m_sort_order,
+ name_preference);
}
} else {
result.AppendError("the target has no associated executable images");
@@ -2050,9 +2057,8 @@ protected:
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) {
- Module *module = module_list.GetModulePointerAtIndex(i);
- if (module) {
+ for (ModuleSP module_sp : module_list.Modules()) {
+ if (module_sp) {
if (num_dumped > 0) {
result.GetOutputStream().EOL();
result.GetOutputStream().EOL();
@@ -2060,8 +2066,9 @@ protected:
if (m_interpreter.WasInterrupted())
break;
num_dumped++;
- DumpModuleSymtab(m_interpreter, result.GetOutputStream(), module,
- m_options.m_sort_order, name_preference);
+ DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
+ module_sp.get(), m_options.m_sort_order,
+ name_preference);
}
}
} else
@@ -2110,23 +2117,22 @@ protected:
if (command.GetArgumentCount() == 0) {
// Dump all sections for all modules images
const size_t num_modules = target->GetImages().GetSize();
- if (num_modules > 0) {
- result.GetOutputStream().Printf("Dumping sections for %" PRIu64
- " modules.\n",
- (uint64_t)num_modules);
- for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
- if (m_interpreter.WasInterrupted())
- break;
- num_dumped++;
- DumpModuleSections(
- m_interpreter, result.GetOutputStream(),
- target->GetImages().GetModulePointerAtIndex(image_idx));
- }
- } else {
+ if (num_modules == 0) {
result.AppendError("the target has no associated executable images");
result.SetStatus(eReturnStatusFailed);
return false;
}
+
+ result.GetOutputStream().Format("Dumping sections for {0} modules.\n",
+ num_modules);
+ for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ if (m_interpreter.WasInterrupted())
+ break;
+ num_dumped++;
+ DumpModuleSections(
+ m_interpreter, result.GetOutputStream(),
+ target->GetImages().GetModulePointerAtIndex(image_idx));
+ }
} else {
// Dump specified images (by basename or fullpath)
const char *arg_cstr;
@@ -2188,7 +2194,8 @@ protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Target *target = &GetSelectedTarget();
- const size_t num_modules = target->GetImages().GetSize();
+ const ModuleList &module_list = target->GetImages();
+ const size_t num_modules = module_list.GetSize();
if (num_modules == 0) {
result.AppendError("the target has no associated executable images");
result.SetStatus(eReturnStatusFailed);
@@ -2197,14 +2204,12 @@ protected:
if (command.GetArgumentCount() == 0) {
// Dump all ASTs for all modules images
- result.GetOutputStream().Printf("Dumping clang ast for %" PRIu64
- " modules.\n",
- (uint64_t)num_modules);
- for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
+ num_modules);
+ for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
if (m_interpreter.WasInterrupted())
break;
- Module *m = target->GetImages().GetModulePointerAtIndex(image_idx);
- if (SymbolFile *sf = m->GetSymbolFile())
+ if (SymbolFile *sf = module_sp->GetSymbolFile())
sf->DumpClangAST(result.GetOutputStream());
}
result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -2269,23 +2274,19 @@ protected:
const ModuleList &target_modules = target->GetImages();
std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
const size_t num_modules = target_modules.GetSize();
- if (num_modules > 0) {
- result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
- " modules.\n",
- (uint64_t)num_modules);
- for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
- if (m_interpreter.WasInterrupted())
- break;
- if (DumpModuleSymbolFile(
- result.GetOutputStream(),
- target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
- num_dumped++;
- }
- } else {
+ if (num_modules == 0) {
result.AppendError("the target has no associated executable images");
result.SetStatus(eReturnStatusFailed);
return false;
}
+ result.GetOutputStream().Format(
+ "Dumping debug symbols for {0} modules.\n", num_modules);
+ for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
+ if (m_interpreter.WasInterrupted())
+ break;
+ if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get()))
+ num_dumped++;
+ }
} else {
// Dump specified images (by basename or fullpath)
const char *arg_cstr;
@@ -2363,15 +2364,13 @@ protected:
const ModuleList &target_modules = target->GetImages();
std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
- const size_t num_modules = target_modules.GetSize();
- if (num_modules > 0) {
+ if (target_modules.GetSize() > 0) {
uint32_t num_dumped = 0;
- for (uint32_t i = 0; i < num_modules; ++i) {
+ for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
if (m_interpreter.WasInterrupted())
break;
if (DumpCompileUnitLineTable(
- m_interpreter, result.GetOutputStream(),
- target_modules.GetModulePointerAtIndexUnlocked(i),
+ m_interpreter, result.GetOutputStream(), module_sp.get(),
file_spec,
m_options.m_verbose ? eDescriptionLevelFull
: eDescriptionLevelBrief))
@@ -3409,10 +3408,35 @@ protected:
continue;
result.GetOutputStream().Printf(
- "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n",
+ "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n",
sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
funcname.AsCString(), start_addr);
+ Args args;
+ target->GetUserSpecifiedTrapHandlerNames(args);
+ size_t count = args.GetArgumentCount();
+ for (size_t i = 0; i < count; i++) {
+ const char *trap_func_name = args.GetArgumentAtIndex(i);
+ if (strcmp(funcname.GetCString(), trap_func_name) == 0)
+ result.GetOutputStream().Printf(
+ "This function is "
+ "treated as a trap handler function via user setting.\n");
+ }
+ PlatformSP platform_sp(target->GetPlatform());
+ if (platform_sp) {
+ const std::vector<ConstString> trap_handler_names(
+ platform_sp->GetTrapHandlerSymbolNames());
+ for (ConstString trap_name : trap_handler_names) {
+ if (trap_name == funcname) {
+ result.GetOutputStream().Printf(
+ "This function's "
+ "name is listed by the platform as a trap handler.\n");
+ }
+ }
+ }
+
+ result.GetOutputStream().Printf("\n");
+
UnwindPlanSP non_callsite_unwind_plan =
func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
if (non_callsite_unwind_plan) {
@@ -3745,9 +3769,9 @@ public:
return false;
case eLookupTypeType:
if (!m_options.m_str.empty()) {
- if (LookupTypeHere(m_interpreter, result.GetOutputStream(),
- *sym_ctx.module_sp, m_options.m_str.c_str(),
- m_options.m_use_regex)) {
+ if (LookupTypeHere(&GetSelectedTarget(), m_interpreter,
+ result.GetOutputStream(), *sym_ctx.module_sp,
+ m_options.m_str.c_str(), m_options.m_use_regex)) {
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
}
@@ -3817,9 +3841,9 @@ public:
case eLookupTypeType:
if (!m_options.m_str.empty()) {
- if (LookupTypeInModule(m_interpreter, result.GetOutputStream(), module,
- m_options.m_str.c_str(),
- m_options.m_use_regex)) {
+ if (LookupTypeInModule(
+ &GetSelectedTarget(), m_interpreter, result.GetOutputStream(),
+ module, m_options.m_str.c_str(), m_options.m_use_regex)) {
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
}
@@ -3868,25 +3892,20 @@ protected:
const ModuleList &target_modules = target->GetImages();
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; ++i) {
- Module *module_pointer =
- target_modules.GetModulePointerAtIndexUnlocked(i);
-
- if (module_pointer != current_module.get() &&
- LookupInModule(m_interpreter,
- target_modules.GetModulePointerAtIndexUnlocked(i),
- result, syntax_error)) {
- result.GetOutputStream().EOL();
- num_successful_lookups++;
- }
- }
- } else {
+ if (target_modules.GetSize() == 0) {
result.AppendError("the target has no associated executable images");
result.SetStatus(eReturnStatusFailed);
return false;
}
+
+ for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
+ if (module_sp != current_module &&
+ LookupInModule(m_interpreter, module_sp.get(), result,
+ syntax_error)) {
+ result.GetOutputStream().EOL();
+ num_successful_lookups++;
+ }
+ }
} else {
// Dump specified images (by basename or fullpath)
const char *arg_cstr;
@@ -4332,7 +4351,6 @@ protected:
module_spec.GetSymbolFileSpec() = symfile_spec;
}
- ArchSpec arch;
bool symfile_exists =
FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
@@ -4405,10 +4423,10 @@ private:
class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
public IOHandlerDelegateMultiline {
public:
- class CommandOptions : public Options {
+ class CommandOptions : public OptionGroup {
public:
CommandOptions()
- : Options(), m_line_start(0), m_line_end(UINT_MAX),
+ : OptionGroup(), m_line_start(0), m_line_end(UINT_MAX),
m_func_name_type_mask(eFunctionNameTypeAuto),
m_sym_ctx_specified(false), m_thread_specified(false),
m_use_one_liner(false), m_one_liner() {}
@@ -4422,7 +4440,8 @@ public:
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
ExecutionContext *execution_context) override {
Status error;
- const int short_option = m_getopt_table[option_idx].val;
+ const int short_option =
+ g_target_stop_hook_add_options[option_idx].short_option;
switch (short_option) {
case 'c':
@@ -4552,20 +4571,75 @@ public:
// Instance variables to hold the values for one_liner options.
bool m_use_one_liner;
std::vector<std::string> m_one_liner;
+
bool m_auto_continue;
};
CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "target stop-hook add",
- "Add a hook to be executed when the target stops.",
+ "Add a hook to be executed when the target stops."
+ "The hook can either be a list of commands or an "
+ "appropriately defined Python class. You can also "
+ "add filters so the hook only runs a certain stop "
+ "points.",
"target stop-hook add"),
IOHandlerDelegateMultiline("DONE",
IOHandlerDelegate::Completion::LLDBCommand),
- m_options() {}
+ m_options(), m_python_class_options("scripted stop-hook", true, 'P') {
+ SetHelpLong(
+ R"(
+Command Based stop-hooks:
+-------------------------
+ Stop hooks can run a list of lldb commands by providing one or more
+ --one-line-command options. The commands will get run in the order they are
+ added. Or you can provide no commands, in which case you will enter a
+ command editor where you can enter the commands to be run.
+
+Python Based Stop Hooks:
+------------------------
+ Stop hooks can be implemented with a suitably defined Python class, whose name
+ is passed in the --python-class option.
+
+ When the stop hook is added, the class is initialized by calling:
+
+ def __init__(self, target, extra_args, dict):
+
+ target: The target that the stop hook is being added to.
+ extra_args: An SBStructuredData Dictionary filled with the -key -value
+ option pairs passed to the command.
+ dict: An implementation detail provided by lldb.
+
+ Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
+ The method has the signature:
+
+ def handle_stop(self, exe_ctx, stream):
+
+ exe_ctx: An SBExecutionContext for the thread that has stopped.
+ stream: An SBStream, anything written to this stream will be printed in the
+ the stop message when the process stops.
+
+ Return Value: The method returns "should_stop". If should_stop is false
+ from all the stop hook executions on threads that stopped
+ with a reason, then the process will continue. Note that this
+ will happen only after all the stop hooks are run.
+
+Filter Options:
+---------------
+ Stop hooks can be set to always run, or to only run when the stopped thread
+ matches the filter options passed on the command line. The available filter
+ options include a shared library or a thread or queue specification,
+ a line range in a source file, a function name or a class name.
+ )");
+ m_all_options.Append(&m_python_class_options,
+ LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
+ LLDB_OPT_SET_FROM_TO(4, 6));
+ m_all_options.Append(&m_options);
+ m_all_options.Finalize();
+ }
~CommandObjectTargetStopHookAdd() override = default;
- Options *GetOptions() override { return &m_options; }
+ Options *GetOptions() override { return &m_all_options; }
protected:
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
@@ -4589,10 +4663,15 @@ protected:
error_sp->Flush();
}
Target *target = GetDebugger().GetSelectedTarget().get();
- if (target)
- target->RemoveStopHookByID(m_stop_hook_sp->GetID());
+ if (target) {
+ target->UndoCreateStopHook(m_stop_hook_sp->GetID());
+ }
} else {
- m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
+ // The IOHandler editor is only for command lines stop hooks:
+ Target::StopHookCommandLine *hook_ptr =
+ static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());
+
+ hook_ptr->SetActionFromString(line);
StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
if (output_sp) {
output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
@@ -4609,7 +4688,10 @@ protected:
m_stop_hook_sp.reset();
Target &target = GetSelectedOrDummyTarget();
- Target::StopHookSP new_hook_sp = target.CreateStopHook();
+ Target::StopHookSP new_hook_sp =
+ target.CreateStopHook(m_python_class_options.GetName().empty() ?
+ Target::StopHook::StopHookKind::CommandBased
+ : Target::StopHook::StopHookKind::ScriptBased);
// First step, make the specifier.
std::unique_ptr<SymbolContextSpecifier> specifier_up;
@@ -4678,11 +4760,30 @@ protected:
new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
if (m_options.m_use_one_liner) {
- // Use one-liners.
- for (auto cmd : m_options.m_one_liner)
- new_hook_sp->GetCommandPointer()->AppendString(cmd.c_str());
+ // This is a command line stop hook:
+ Target::StopHookCommandLine *hook_ptr =
+ static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());
+ hook_ptr->SetActionFromStrings(m_options.m_one_liner);
result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
new_hook_sp->GetID());
+ } else if (!m_python_class_options.GetName().empty()) {
+ // This is a scripted stop hook:
+ Target::StopHookScripted *hook_ptr =
+ static_cast<Target::StopHookScripted *>(new_hook_sp.get());
+ Status error = hook_ptr->SetScriptCallback(
+ m_python_class_options.GetName(),
+ m_python_class_options.GetStructuredData());
+ if (error.Success())
+ result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
+ new_hook_sp->GetID());
+ else {
+ // FIXME: Set the stop hook ID counter back.
+ result.AppendErrorWithFormat("Couldn't add stop hook: %s",
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ target.UndoCreateStopHook(new_hook_sp->GetID());
+ return false;
+ }
} else {
m_stop_hook_sp = new_hook_sp;
m_interpreter.GetLLDBCommandsFromIOHandler("> ", // Prompt
@@ -4695,6 +4796,9 @@ protected:
private:
CommandOptions m_options;
+ OptionGroupPythonClassWithDict m_python_class_options;
+ OptionGroupOptions m_all_options;
+
Target::StopHookSP m_stop_hook_sp;
};
@@ -4711,6 +4815,14 @@ public:
~CommandObjectTargetStopHookDelete() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
+ request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Target &target = GetSelectedOrDummyTarget();
@@ -4759,6 +4871,16 @@ public:
~CommandObjectTargetStopHookEnableDisable() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex())
+ return;
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
+ request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Target &target = GetSelectedOrDummyTarget();
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp
index f0ad1798fec6..f4ce5cc599cb 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp
@@ -8,6 +8,10 @@
#include "CommandObjectThread.h"
+#include <sstream>
+
+#include "CommandObjectThreadUtil.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -26,207 +30,12 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/ThreadPlanStepInRange.h"
+#include "lldb/Target/Trace.h"
#include "lldb/Utility/State.h"
using namespace lldb;
using namespace lldb_private;
-// CommandObjectIterateOverThreads
-
-class CommandObjectIterateOverThreads : public CommandObjectParsed {
-
- class UniqueStack {
-
- public:
- UniqueStack(std::stack<lldb::addr_t> stack_frames, uint32_t thread_index_id)
- : m_stack_frames(stack_frames) {
- m_thread_index_ids.push_back(thread_index_id);
- }
-
- void AddThread(uint32_t thread_index_id) const {
- m_thread_index_ids.push_back(thread_index_id);
- }
-
- const std::vector<uint32_t> &GetUniqueThreadIndexIDs() const {
- return m_thread_index_ids;
- }
-
- lldb::tid_t GetRepresentativeThread() const {
- return m_thread_index_ids.front();
- }
-
- friend bool inline operator<(const UniqueStack &lhs,
- const UniqueStack &rhs) {
- return lhs.m_stack_frames < rhs.m_stack_frames;
- }
-
- protected:
- // Mark the thread index as mutable, as we don't care about it from a const
- // perspective, we only care about m_stack_frames so we keep our std::set
- // sorted.
- mutable std::vector<uint32_t> m_thread_index_ids;
- std::stack<lldb::addr_t> m_stack_frames;
- };
-
-public:
- CommandObjectIterateOverThreads(CommandInterpreter &interpreter,
- const char *name, const char *help,
- const char *syntax, uint32_t flags)
- : CommandObjectParsed(interpreter, name, help, syntax, flags) {}
-
- ~CommandObjectIterateOverThreads() override = default;
-
- bool DoExecute(Args &command, CommandReturnObject &result) override {
- result.SetStatus(m_success_return);
-
- bool all_threads = false;
- if (command.GetArgumentCount() == 0) {
- Thread *thread = m_exe_ctx.GetThreadPtr();
- if (!thread || !HandleOneThread(thread->GetID(), result))
- return false;
- return result.Succeeded();
- } else if (command.GetArgumentCount() == 1) {
- all_threads = ::strcmp(command.GetArgumentAtIndex(0), "all") == 0;
- m_unique_stacks = ::strcmp(command.GetArgumentAtIndex(0), "unique") == 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 (all_threads || m_unique_stacks) {
- Process *process = m_exe_ctx.GetProcessPtr();
-
- 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();
-
- std::lock_guard<std::recursive_mutex> guard(
- process->GetThreadList().GetMutex());
-
- for (size_t i = 0; i < num_args; i++) {
- uint32_t thread_idx;
- if (!llvm::to_integer(command.GetArgumentAtIndex(i), thread_idx)) {
- result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n",
- command.GetArgumentAtIndex(i));
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- 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;
- }
-
- tids.push_back(thread->GetID());
- }
- }
-
- if (m_unique_stacks) {
- // Iterate over threads, finding unique stack buckets.
- std::set<UniqueStack> unique_stacks;
- for (const lldb::tid_t &tid : tids) {
- if (!BucketThread(tid, unique_stacks, result)) {
- return false;
- }
- }
-
- // Write the thread id's and unique call stacks to the output stream
- Stream &strm = result.GetOutputStream();
- Process *process = m_exe_ctx.GetProcessPtr();
- for (const UniqueStack &stack : unique_stacks) {
- // List the common thread ID's
- const std::vector<uint32_t> &thread_index_ids =
- stack.GetUniqueThreadIndexIDs();
- strm.Format("{0} thread(s) ", thread_index_ids.size());
- for (const uint32_t &thread_index_id : thread_index_ids) {
- strm.Format("#{0} ", thread_index_id);
- }
- strm.EOL();
-
- // List the shared call stack for this set of threads
- uint32_t representative_thread_id = stack.GetRepresentativeThread();
- ThreadSP thread = process->GetThreadList().FindThreadByIndexID(
- representative_thread_id);
- if (!HandleOneThread(thread->GetID(), result)) {
- return false;
- }
- }
- } else {
- 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.
- // The result is set to m_success_return (defaults to
- // eReturnStatusSuccessFinishResult) before the iteration, so you only need
- // to set the return status in HandleOneThread if you want to indicate an
- // error. If m_add_return is true, a blank line will be inserted between each
- // of the listings (except the last one.)
-
- virtual bool HandleOneThread(lldb::tid_t, CommandReturnObject &result) = 0;
-
- bool BucketThread(lldb::tid_t tid, std::set<UniqueStack> &unique_stacks,
- CommandReturnObject &result) {
- // Grab the corresponding thread for the given thread id.
- Process *process = m_exe_ctx.GetProcessPtr();
- Thread *thread = process->GetThreadList().FindThreadByID(tid).get();
- if (thread == nullptr) {
- result.AppendErrorWithFormatv("Failed to process thread #{0}.\n", tid);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- // Collect the each frame's address for this call-stack
- std::stack<lldb::addr_t> stack_frames;
- const uint32_t frame_count = thread->GetStackFrameCount();
- for (uint32_t frame_index = 0; frame_index < frame_count; frame_index++) {
- const lldb::StackFrameSP frame_sp =
- thread->GetStackFrameAtIndex(frame_index);
- const lldb::addr_t pc = frame_sp->GetStackID().GetPC();
- stack_frames.push(pc);
- }
-
- uint32_t thread_index_id = thread->GetIndexID();
- UniqueStack new_unique_stack(stack_frames, thread_index_id);
-
- // Try to match the threads stack to and existing entry.
- std::set<UniqueStack>::iterator matching_stack =
- unique_stacks.find(new_unique_stack);
- if (matching_stack != unique_stacks.end()) {
- matching_stack->AddThread(thread_index_id);
- } else {
- unique_stacks.insert(new_unique_stack);
- }
- return true;
- }
-
- ReturnStatus m_success_return = eReturnStatusSuccessFinishResult;
- bool m_unique_stacks = false;
- bool m_add_return = true;
-};
-
// CommandObjectThreadBacktrace
#define LLDB_OPTIONS_thread_backtrace
#include "CommandOptions.inc"
@@ -482,8 +291,16 @@ public:
// Check if we are in Non-Stop mode
TargetSP target_sp =
execution_context ? execution_context->GetTargetSP() : TargetSP();
- if (target_sp && target_sp->GetNonStopModeEnabled())
+ if (target_sp && target_sp->GetNonStopModeEnabled()) {
+ // NonStopMode runs all threads by definition, so when it is on we don't
+ // need to check the process setting for runs all threads.
m_run_mode = eOnlyThisThread;
+ } else {
+ ProcessSP process_sp =
+ execution_context ? execution_context->GetProcessSP() : ProcessSP();
+ if (process_sp && process_sp->GetSteppingRunsAllThreads())
+ m_run_mode = eAllThreads;
+ }
m_avoid_regexp.clear();
m_step_in_target.clear();
@@ -541,6 +358,17 @@ public:
~CommandObjectThreadStepWithTypeAndScope() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex())
+ return;
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
+ request, nullptr);
+ }
+
Options *GetOptions() override { return &m_all_options; }
protected:
@@ -612,8 +440,7 @@ protected:
if (m_options.m_run_mode == eAllThreads)
bool_stop_other_threads = false;
else if (m_options.m_run_mode == eOnlyDuringStepping)
- bool_stop_other_threads =
- (m_step_type != eStepTypeOut && m_step_type != eStepTypeScripted);
+ bool_stop_other_threads = (m_step_type != eStepTypeOut);
else
bool_stop_other_threads = true;
@@ -808,6 +635,14 @@ public:
~CommandObjectThreadContinue() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
+ request, nullptr);
+ }
+
bool DoExecute(Args &command, CommandReturnObject &result) override {
bool synchronous_execution = m_interpreter.GetSynchronous();
@@ -1300,6 +1135,17 @@ public:
~CommandObjectThreadSelect() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex())
+ return;
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
+ request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Process *process = m_exe_ctx.GetProcessPtr();
@@ -1431,6 +1277,14 @@ public:
~CommandObjectThreadInfo() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
+ request, nullptr);
+ }
+
Options *GetOptions() override { return &m_options; }
bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
@@ -1475,6 +1329,14 @@ public:
~CommandObjectThreadException() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
+ request, nullptr);
+ }
+
bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
ThreadSP thread_sp =
m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
@@ -1929,8 +1791,7 @@ public:
protected:
bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
// If we have already handled this from a -t option, skip it here.
- if (std::find(m_options.m_tids.begin(), m_options.m_tids.end(), tid) !=
- m_options.m_tids.end())
+ if (llvm::is_contained(m_options.m_tids, tid))
return true;
Process *process = m_exe_ctx.GetProcessPtr();
@@ -1978,6 +1839,15 @@ public:
~CommandObjectThreadPlanDiscard() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (!m_exe_ctx.HasThreadScope() || request.GetCursorIndex())
+ return;
+
+ m_exe_ctx.GetThreadPtr()->AutoCompleteThreadPlans(request);
+ }
+
bool DoExecute(Args &args, CommandReturnObject &result) override {
Thread *thread = m_exe_ctx.GetThreadPtr();
if (args.GetArgumentCount() != 1) {
@@ -2104,6 +1974,271 @@ public:
~CommandObjectMultiwordThreadPlan() override = default;
};
+// Next are the subcommands of CommandObjectMultiwordTrace
+
+// CommandObjectTraceStart
+
+/// This class works by delegating the logic to the actual trace plug-in that
+/// can support the current process.
+class CommandObjectTraceStart : public CommandObjectProxy {
+public:
+ CommandObjectTraceStart(CommandInterpreter &interpreter)
+ : CommandObjectProxy(interpreter, "thread trace start",
+ "Start tracing threads with the corresponding trace "
+ "plug-in for the current process.",
+ "thread trace start [<trace-options>]") {}
+
+protected:
+ llvm::Expected<CommandObjectSP> DoGetProxyCommandObject() {
+ ProcessSP process_sp = m_interpreter.GetExecutionContext().GetProcessSP();
+
+ if (!process_sp)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Process not available.");
+ if (!process_sp->IsAlive())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Process must be launched.");
+
+ llvm::Expected<TraceTypeInfo> trace_type =
+ process_sp->GetSupportedTraceType();
+
+ if (!trace_type)
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(), "Tracing is not supported. %s",
+ llvm::toString(trace_type.takeError()).c_str());
+
+ CommandObjectSP delegate_sp =
+ PluginManager::GetTraceStartCommand(trace_type->name, m_interpreter);
+ if (!delegate_sp)
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "No trace plug-in matches the specified type: \"%s\"",
+ trace_type->name.c_str());
+ return delegate_sp;
+ }
+
+ CommandObject *GetProxyCommandObject() override {
+ if (llvm::Expected<CommandObjectSP> delegate = DoGetProxyCommandObject()) {
+ m_delegate_sp = *delegate;
+ m_delegate_error.clear();
+ return m_delegate_sp.get();
+ } else {
+ m_delegate_sp.reset();
+ m_delegate_error = llvm::toString(delegate.takeError());
+ return nullptr;
+ }
+ }
+
+private:
+ llvm::StringRef GetUnsupportedError() override { return m_delegate_error; }
+
+ CommandObjectSP m_delegate_sp;
+ std::string m_delegate_error;
+};
+
+// CommandObjectTraceStop
+
+class CommandObjectTraceStop : public CommandObjectIterateOverThreads {
+public:
+ CommandObjectTraceStop(CommandInterpreter &interpreter)
+ : CommandObjectIterateOverThreads(
+ interpreter, "thread trace stop",
+ "Stop tracing threads. "
+ "Defaults to the current thread. Thread indices can be "
+ "specified as arguments.\n Use the thread-index \"all\" to trace "
+ "all threads.",
+ "thread trace stop [<thread-index> <thread-index> ...]",
+ eCommandRequiresProcess | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused |
+ eCommandProcessMustBeTraced) {}
+
+ ~CommandObjectTraceStop() override = default;
+
+ bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
+ const Thread &thread =
+ *m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
+ Trace &trace = *m_exe_ctx.GetTargetSP()->GetTrace();
+
+ if (llvm::Error err = trace.StopTracingThread(thread)) {
+ result.AppendErrorWithFormat("Failed stopping thread %" PRIu64 ": %s\n",
+ tid, toString(std::move(err)).c_str());
+ result.SetStatus(eReturnStatusFailed);
+ }
+
+ // We don't return false on errors to try to stop as many threads as
+ // possible.
+ return true;
+ }
+};
+
+// CommandObjectTraceDumpInstructions
+#define LLDB_OPTIONS_thread_trace_dump_instructions
+#include "CommandOptions.inc"
+
+class CommandObjectTraceDumpInstructions
+ : public CommandObjectIterateOverThreads {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'c': {
+ int32_t count;
+ if (option_arg.empty() || option_arg.getAsInteger(0, count) ||
+ count < 0)
+ error.SetErrorStringWithFormat(
+ "invalid integer value for option '%s'",
+ option_arg.str().c_str());
+ else
+ m_count = count;
+ break;
+ }
+ case 'p': {
+ int32_t position;
+ if (option_arg.empty() || option_arg.getAsInteger(0, position) ||
+ position < 0)
+ error.SetErrorStringWithFormat(
+ "invalid integer value for option '%s'",
+ option_arg.str().c_str());
+ else
+ m_position = position;
+ break;
+ }
+ case 'r': {
+ m_raw = true;
+ break;
+ }
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_count = kDefaultCount;
+ m_position = llvm::None;
+ m_raw = false;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_thread_trace_dump_instructions_options);
+ }
+
+ static const size_t kDefaultCount = 20;
+
+ // Instance variables to hold the values for command options.
+ size_t m_count;
+ llvm::Optional<ssize_t> m_position;
+ bool m_raw;
+ };
+
+ CommandObjectTraceDumpInstructions(CommandInterpreter &interpreter)
+ : CommandObjectIterateOverThreads(
+ interpreter, "thread trace dump instructions",
+ "Dump the traced instructions 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 | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused |
+ eCommandProcessMustBeTraced),
+ m_options(), m_create_repeat_command_just_invoked(false) {}
+
+ ~CommandObjectTraceDumpInstructions() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ const char *GetRepeatCommand(Args &current_command_args,
+ uint32_t index) override {
+ current_command_args.GetCommandString(m_repeat_command);
+ m_create_repeat_command_just_invoked = true;
+ m_consecutive_repetitions = 0;
+ return m_repeat_command.c_str();
+ }
+
+protected:
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ if (IsRepeatCommand())
+ m_consecutive_repetitions++;
+ bool status = CommandObjectIterateOverThreads::DoExecute(args, result);
+
+ m_create_repeat_command_just_invoked = false;
+ return status;
+ }
+
+ bool IsRepeatCommand() {
+ return !m_repeat_command.empty() && !m_create_repeat_command_just_invoked;
+ }
+
+ bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
+ const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace();
+ ThreadSP thread_sp =
+ m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
+
+ size_t count = m_options.m_count;
+ ssize_t position = m_options.m_position.getValueOr(
+ trace_sp->GetCursorPosition(*thread_sp)) -
+ m_consecutive_repetitions * count;
+ if (position < 0)
+ result.SetError("error: no more data");
+ else
+ trace_sp->DumpTraceInstructions(*thread_sp, result.GetOutputStream(),
+ count, position, m_options.m_raw);
+ return true;
+ }
+
+ CommandOptions m_options;
+
+ // Repeat command helpers
+ std::string m_repeat_command;
+ bool m_create_repeat_command_just_invoked;
+ size_t m_consecutive_repetitions = 0;
+};
+
+// CommandObjectMultiwordTraceDump
+class CommandObjectMultiwordTraceDump : public CommandObjectMultiword {
+public:
+ CommandObjectMultiwordTraceDump(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "dump",
+ "Commands for displaying trace information of the threads "
+ "in the current process.",
+ "thread trace dump <subcommand> [<subcommand objects>]") {
+ LoadSubCommand(
+ "instructions",
+ CommandObjectSP(new CommandObjectTraceDumpInstructions(interpreter)));
+ }
+ ~CommandObjectMultiwordTraceDump() override = default;
+};
+
+// CommandObjectMultiwordTrace
+class CommandObjectMultiwordTrace : public CommandObjectMultiword {
+public:
+ CommandObjectMultiwordTrace(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "trace",
+ "Commands for operating on traces of the threads in the current "
+ "process.",
+ "thread trace <subcommand> [<subcommand objects>]") {
+ LoadSubCommand("dump", CommandObjectSP(new CommandObjectMultiwordTraceDump(
+ interpreter)));
+ LoadSubCommand("start",
+ CommandObjectSP(new CommandObjectTraceStart(interpreter)));
+ LoadSubCommand("stop",
+ CommandObjectSP(new CommandObjectTraceStop(interpreter)));
+ }
+
+ ~CommandObjectMultiwordTrace() override = default;
+};
+
// CommandObjectMultiwordThread
CommandObjectMultiwordThread::CommandObjectMultiwordThread(
@@ -2179,6 +2314,8 @@ CommandObjectMultiwordThread::CommandObjectMultiwordThread(
LoadSubCommand("plan", CommandObjectSP(new CommandObjectMultiwordThreadPlan(
interpreter)));
+ LoadSubCommand("trace",
+ CommandObjectSP(new CommandObjectMultiwordTrace(interpreter)));
}
CommandObjectMultiwordThread::~CommandObjectMultiwordThread() = default;
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.cpp
new file mode 100644
index 000000000000..b93698c7be60
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.cpp
@@ -0,0 +1,158 @@
+//===-- CommandObjectThreadUtil.cpp -----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectThreadUtil.h"
+
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm;
+
+CommandObjectIterateOverThreads::CommandObjectIterateOverThreads(
+ CommandInterpreter &interpreter, const char *name, const char *help,
+ const char *syntax, uint32_t flags)
+ : CommandObjectParsed(interpreter, name, help, syntax, flags) {}
+
+bool CommandObjectIterateOverThreads::DoExecute(Args &command,
+ CommandReturnObject &result) {
+ result.SetStatus(m_success_return);
+
+ bool all_threads = false;
+ if (command.GetArgumentCount() == 0) {
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+ if (!thread || !HandleOneThread(thread->GetID(), result))
+ return false;
+ return result.Succeeded();
+ } else if (command.GetArgumentCount() == 1) {
+ all_threads = ::strcmp(command.GetArgumentAtIndex(0), "all") == 0;
+ m_unique_stacks = ::strcmp(command.GetArgumentAtIndex(0), "unique") == 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 (all_threads || m_unique_stacks) {
+ Process *process = m_exe_ctx.GetProcessPtr();
+
+ 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();
+
+ std::lock_guard<std::recursive_mutex> guard(
+ process->GetThreadList().GetMutex());
+
+ for (size_t i = 0; i < num_args; i++) {
+ uint32_t thread_idx;
+ if (!llvm::to_integer(command.GetArgumentAtIndex(i), thread_idx)) {
+ result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n",
+ command.GetArgumentAtIndex(i));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ 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;
+ }
+
+ tids.push_back(thread->GetID());
+ }
+ }
+
+ if (m_unique_stacks) {
+ // Iterate over threads, finding unique stack buckets.
+ std::set<UniqueStack> unique_stacks;
+ for (const lldb::tid_t &tid : tids) {
+ if (!BucketThread(tid, unique_stacks, result)) {
+ return false;
+ }
+ }
+
+ // Write the thread id's and unique call stacks to the output stream
+ Stream &strm = result.GetOutputStream();
+ Process *process = m_exe_ctx.GetProcessPtr();
+ for (const UniqueStack &stack : unique_stacks) {
+ // List the common thread ID's
+ const std::vector<uint32_t> &thread_index_ids =
+ stack.GetUniqueThreadIndexIDs();
+ strm.Format("{0} thread(s) ", thread_index_ids.size());
+ for (const uint32_t &thread_index_id : thread_index_ids) {
+ strm.Format("#{0} ", thread_index_id);
+ }
+ strm.EOL();
+
+ // List the shared call stack for this set of threads
+ uint32_t representative_thread_id = stack.GetRepresentativeThread();
+ ThreadSP thread = process->GetThreadList().FindThreadByIndexID(
+ representative_thread_id);
+ if (!HandleOneThread(thread->GetID(), result)) {
+ return false;
+ }
+ }
+ } else {
+ 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();
+}
+
+bool CommandObjectIterateOverThreads::BucketThread(
+ lldb::tid_t tid, std::set<UniqueStack> &unique_stacks,
+ CommandReturnObject &result) {
+ // Grab the corresponding thread for the given thread id.
+ Process *process = m_exe_ctx.GetProcessPtr();
+ Thread *thread = process->GetThreadList().FindThreadByID(tid).get();
+ if (thread == nullptr) {
+ result.AppendErrorWithFormatv("Failed to process thread #{0}.\n", tid);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // Collect the each frame's address for this call-stack
+ std::stack<lldb::addr_t> stack_frames;
+ const uint32_t frame_count = thread->GetStackFrameCount();
+ for (uint32_t frame_index = 0; frame_index < frame_count; frame_index++) {
+ const lldb::StackFrameSP frame_sp =
+ thread->GetStackFrameAtIndex(frame_index);
+ const lldb::addr_t pc = frame_sp->GetStackID().GetPC();
+ stack_frames.push(pc);
+ }
+
+ uint32_t thread_index_id = thread->GetIndexID();
+ UniqueStack new_unique_stack(stack_frames, thread_index_id);
+
+ // Try to match the threads stack to and existing entry.
+ std::set<UniqueStack>::iterator matching_stack =
+ unique_stacks.find(new_unique_stack);
+ if (matching_stack != unique_stacks.end()) {
+ matching_stack->AddThread(thread_index_id);
+ } else {
+ unique_stacks.insert(new_unique_stack);
+ }
+ return true;
+}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.h
new file mode 100644
index 000000000000..7122982d8943
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.h
@@ -0,0 +1,81 @@
+//===-- CommandObjectThreadUtil.h -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREADUTIL_H
+#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREADUTIL_H
+
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+
+namespace lldb_private {
+
+class CommandObjectIterateOverThreads : public CommandObjectParsed {
+
+ class UniqueStack {
+ public:
+ UniqueStack(std::stack<lldb::addr_t> stack_frames, uint32_t thread_index_id)
+ : m_stack_frames(stack_frames) {
+ m_thread_index_ids.push_back(thread_index_id);
+ }
+
+ void AddThread(uint32_t thread_index_id) const {
+ m_thread_index_ids.push_back(thread_index_id);
+ }
+
+ const std::vector<uint32_t> &GetUniqueThreadIndexIDs() const {
+ return m_thread_index_ids;
+ }
+
+ lldb::tid_t GetRepresentativeThread() const {
+ return m_thread_index_ids.front();
+ }
+
+ friend bool inline operator<(const UniqueStack &lhs,
+ const UniqueStack &rhs) {
+ return lhs.m_stack_frames < rhs.m_stack_frames;
+ }
+
+ protected:
+ // Mark the thread index as mutable, as we don't care about it from a const
+ // perspective, we only care about m_stack_frames so we keep our std::set
+ // sorted.
+ mutable std::vector<uint32_t> m_thread_index_ids;
+ std::stack<lldb::addr_t> m_stack_frames;
+ };
+
+public:
+ CommandObjectIterateOverThreads(CommandInterpreter &interpreter,
+ const char *name, const char *help,
+ const char *syntax, uint32_t flags);
+
+ ~CommandObjectIterateOverThreads() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override;
+
+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.
+ // The result is set to m_success_return (defaults to
+ // eReturnStatusSuccessFinishResult) before the iteration, so you only need
+ // to set the return status in HandleOneThread if you want to indicate an
+ // error. If m_add_return is true, a blank line will be inserted between each
+ // of the listings (except the last one.)
+
+ virtual bool HandleOneThread(lldb::tid_t, CommandReturnObject &result) = 0;
+
+ bool BucketThread(lldb::tid_t tid, std::set<UniqueStack> &unique_stacks,
+ CommandReturnObject &result);
+
+ lldb::ReturnStatus m_success_return = lldb::eReturnStatusSuccessFinishResult;
+ bool m_unique_stacks = false;
+ bool m_add_return = true;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREADUTIL_H
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp
new file mode 100644
index 000000000000..170630b85b2e
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp
@@ -0,0 +1,305 @@
+//===-- CommandObjectTrace.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectTrace.h"
+
+#include "llvm/Support/JSON.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/OptionParser.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandObject.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Interpreter/OptionGroupFormat.h"
+#include "lldb/Interpreter/OptionValueBoolean.h"
+#include "lldb/Interpreter/OptionValueLanguage.h"
+#include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Target/Trace.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm;
+
+// CommandObjectTraceLoad
+#define LLDB_OPTIONS_trace_load
+#include "CommandOptions.inc"
+
+#pragma mark CommandObjectTraceLoad
+
+class CommandObjectTraceLoad : public CommandObjectParsed {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'v': {
+ m_verbose = true;
+ break;
+ }
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_verbose = false;
+ }
+
+ ArrayRef<OptionDefinition> GetDefinitions() override {
+ return makeArrayRef(g_trace_load_options);
+ }
+
+ bool m_verbose; // Enable verbose logging for debugging purposes.
+ };
+
+ CommandObjectTraceLoad(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "trace load",
+ "Load a processor trace session from a JSON file.",
+ "trace load"),
+ m_options() {}
+
+ ~CommandObjectTraceLoad() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (command.size() != 1) {
+ result.AppendError(
+ "a single path to a JSON file containing a trace session"
+ "is required");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ auto end_with_failure = [&result](llvm::Error err) -> bool {
+ result.AppendErrorWithFormat("%s\n",
+ llvm::toString(std::move(err)).c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ };
+
+ FileSpec json_file(command[0].ref());
+
+ auto buffer_or_error = llvm::MemoryBuffer::getFile(json_file.GetPath());
+ if (!buffer_or_error) {
+ return end_with_failure(llvm::createStringError(
+ std::errc::invalid_argument, "could not open input file: %s - %s.",
+ json_file.GetPath().c_str(),
+ buffer_or_error.getError().message().c_str()));
+ }
+
+ llvm::Expected<json::Value> session_file =
+ json::parse(buffer_or_error.get()->getBuffer().str());
+ if (!session_file)
+ return end_with_failure(session_file.takeError());
+
+ if (Expected<lldb::TraceSP> traceOrErr =
+ Trace::FindPlugin(GetDebugger(), *session_file,
+ json_file.GetDirectory().AsCString())) {
+ lldb::TraceSP trace_sp = traceOrErr.get();
+ if (m_options.m_verbose)
+ result.AppendMessageWithFormat("loading trace with plugin %s\n",
+ trace_sp->GetPluginName().AsCString());
+ } else
+ return end_with_failure(traceOrErr.takeError());
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+
+ CommandOptions m_options;
+};
+
+// CommandObjectTraceDump
+#define LLDB_OPTIONS_trace_dump
+#include "CommandOptions.inc"
+
+#pragma mark CommandObjectTraceDump
+
+class CommandObjectTraceDump : public CommandObjectParsed {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'v': {
+ m_verbose = true;
+ break;
+ }
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_verbose = false;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_trace_dump_options);
+ }
+
+ bool m_verbose; // Enable verbose logging for debugging purposes.
+ };
+
+ CommandObjectTraceDump(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "trace dump",
+ "Dump the loaded processor trace data.",
+ "trace dump"),
+ m_options() {}
+
+ ~CommandObjectTraceDump() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Status error;
+ // TODO: fill in the dumping code here!
+ if (error.Success()) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("%s\n", error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ return result.Succeeded();
+ }
+
+ CommandOptions m_options;
+};
+
+// CommandObjectTraceSchema
+#define LLDB_OPTIONS_trace_schema
+#include "CommandOptions.inc"
+
+#pragma mark CommandObjectTraceSchema
+
+class CommandObjectTraceSchema : public CommandObjectParsed {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'v': {
+ m_verbose = true;
+ break;
+ }
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_verbose = false;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_trace_schema_options);
+ }
+
+ bool m_verbose; // Enable verbose logging for debugging purposes.
+ };
+
+ CommandObjectTraceSchema(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "trace schema",
+ "Show the schema of the given trace plugin.",
+ "trace schema <plug-in>. Use the plug-in name "
+ "\"all\" to see all schemas.\n"),
+ m_options() {}
+
+ ~CommandObjectTraceSchema() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Status error;
+ if (command.empty()) {
+ result.SetError(
+ "trace schema cannot be invoked without a plug-in as argument");
+ return false;
+ }
+
+ StringRef plugin_name(command[0].c_str());
+ if (plugin_name == "all") {
+ size_t index = 0;
+ while (true) {
+ StringRef schema = PluginManager::GetTraceSchema(index++);
+ if (schema.empty())
+ break;
+
+ result.AppendMessage(schema);
+ }
+ } else {
+ if (Expected<StringRef> schemaOrErr =
+ Trace::FindPluginSchema(plugin_name))
+ result.AppendMessage(*schemaOrErr);
+ else
+ error = schemaOrErr.takeError();
+ }
+
+ if (error.Success()) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("%s\n", error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ return result.Succeeded();
+ }
+
+ CommandOptions m_options;
+};
+
+// CommandObjectTrace
+
+CommandObjectTrace::CommandObjectTrace(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "trace",
+ "Commands for loading and using processor "
+ "trace information.",
+ "trace [<sub-command-options>]") {
+ LoadSubCommand("load",
+ CommandObjectSP(new CommandObjectTraceLoad(interpreter)));
+ LoadSubCommand("dump",
+ CommandObjectSP(new CommandObjectTraceDump(interpreter)));
+ LoadSubCommand("schema",
+ CommandObjectSP(new CommandObjectTraceSchema(interpreter)));
+}
+
+CommandObjectTrace::~CommandObjectTrace() = default;
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.h
new file mode 100644
index 000000000000..2dca0e26b243
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.h
@@ -0,0 +1,25 @@
+//===-- CommandObjectTrace.h ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTTRACE_H
+#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTTRACE_H
+
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+
+namespace lldb_private {
+
+class CommandObjectTrace : public CommandObjectMultiword {
+public:
+ CommandObjectTrace(CommandInterpreter &interpreter);
+
+ ~CommandObjectTrace() override;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTTRACE_H
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp
index b2020f26621f..004c066b57aa 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp
@@ -37,6 +37,9 @@
#include <functional>
#include <memory>
+#define CHECK_FORMATTER_KIND_MASK(VAL) \
+ ((m_formatter_kind_mask & (VAL)) == (VAL))
+
using namespace lldb;
using namespace lldb_private;
@@ -777,6 +780,39 @@ public:
~CommandObjectTypeFormatterDelete() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex())
+ return;
+
+ DataVisualization::Categories::ForEach(
+ [this, &request](const lldb::TypeCategoryImplSP &category_sp) {
+ if (CHECK_FORMATTER_KIND_MASK(eFormatCategoryItemValue))
+ category_sp->GetTypeFormatsContainer()->AutoComplete(request);
+ if (CHECK_FORMATTER_KIND_MASK(eFormatCategoryItemRegexValue))
+ category_sp->GetRegexTypeFormatsContainer()->AutoComplete(request);
+
+ if (CHECK_FORMATTER_KIND_MASK(eFormatCategoryItemSummary))
+ category_sp->GetTypeSummariesContainer()->AutoComplete(request);
+ if (CHECK_FORMATTER_KIND_MASK(eFormatCategoryItemRegexSummary))
+ category_sp->GetRegexTypeSummariesContainer()->AutoComplete(
+ request);
+
+ if (CHECK_FORMATTER_KIND_MASK(eFormatCategoryItemFilter))
+ category_sp->GetTypeFiltersContainer()->AutoComplete(request);
+ if (CHECK_FORMATTER_KIND_MASK(eFormatCategoryItemRegexFilter))
+ category_sp->GetRegexTypeFiltersContainer()->AutoComplete(request);
+
+ if (CHECK_FORMATTER_KIND_MASK(eFormatCategoryItemSynth))
+ category_sp->GetTypeSyntheticsContainer()->AutoComplete(request);
+ if (CHECK_FORMATTER_KIND_MASK(eFormatCategoryItemRegexSynth))
+ category_sp->GetRegexTypeSyntheticsContainer()->AutoComplete(
+ request);
+ return true;
+ });
+ }
+
protected:
virtual bool FormatterSpecificDeletion(ConstString typeCS) { return false; }
@@ -1066,13 +1102,15 @@ protected:
TypeCategoryImpl::ForEachCallbacks<FormatterType> foreach;
foreach
.SetExact([&result, &formatter_regex, &any_printed](
- ConstString name,
+ const TypeMatcher &type_matcher,
const FormatterSharedPointer &format_sp) -> bool {
if (formatter_regex) {
bool escape = true;
- if (name.GetStringRef() == formatter_regex->GetText()) {
+ if (type_matcher.CreatedBySameMatchString(
+ ConstString(formatter_regex->GetText()))) {
escape = false;
- } else if (formatter_regex->Execute(name.GetStringRef())) {
+ } else if (formatter_regex->Execute(
+ type_matcher.GetMatchString().GetStringRef())) {
escape = false;
}
@@ -1081,20 +1119,23 @@ protected:
}
any_printed = true;
- result.GetOutputStream().Printf("%s: %s\n", name.AsCString(),
- format_sp->GetDescription().c_str());
+ result.GetOutputStream().Printf(
+ "%s: %s\n", type_matcher.GetMatchString().GetCString(),
+ format_sp->GetDescription().c_str());
return true;
});
foreach
.SetWithRegex([&result, &formatter_regex, &any_printed](
- const RegularExpression &regex,
+ const TypeMatcher &type_matcher,
const FormatterSharedPointer &format_sp) -> bool {
if (formatter_regex) {
bool escape = true;
- if (regex.GetText() == formatter_regex->GetText()) {
+ if (type_matcher.CreatedBySameMatchString(
+ ConstString(formatter_regex->GetText()))) {
escape = false;
- } else if (formatter_regex->Execute(regex.GetText())) {
+ } else if (formatter_regex->Execute(
+ type_matcher.GetMatchString().GetStringRef())) {
escape = false;
}
@@ -1103,9 +1144,9 @@ protected:
}
any_printed = true;
- result.GetOutputStream().Printf("%s: %s\n",
- regex.GetText().str().c_str(),
- format_sp->GetDescription().c_str());
+ result.GetOutputStream().Printf(
+ "%s: %s\n", type_matcher.GetMatchString().GetCString(),
+ format_sp->GetDescription().c_str());
return true;
});
@@ -1681,10 +1722,10 @@ protected:
if (DataVisualization::NamedSummaryFormats::GetCount() > 0) {
result.GetOutputStream().Printf("Named summaries:\n");
DataVisualization::NamedSummaryFormats::ForEach(
- [&result](ConstString name,
+ [&result](const TypeMatcher &type_matcher,
const TypeSummaryImplSP &summary_sp) -> bool {
result.GetOutputStream().Printf(
- "%s: %s\n", name.AsCString(),
+ "%s: %s\n", type_matcher.GetMatchString().GetCString(),
summary_sp->GetDescription().c_str());
return true;
});
@@ -1764,6 +1805,14 @@ public:
~CommandObjectTypeCategoryDefine() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(),
+ CommandCompletions::eTypeCategoryNameCompletion, request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -1860,6 +1909,14 @@ public:
~CommandObjectTypeCategoryEnable() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(),
+ CommandCompletions::eTypeCategoryNameCompletion, request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -1922,6 +1979,14 @@ public:
~CommandObjectTypeCategoryDelete() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(),
+ CommandCompletions::eTypeCategoryNameCompletion, request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -2027,6 +2092,14 @@ public:
~CommandObjectTypeCategoryDisable() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(),
+ CommandCompletions::eTypeCategoryNameCompletion, request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -2084,6 +2157,16 @@ public:
~CommandObjectTypeCategoryList() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex())
+ return;
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(),
+ CommandCompletions::eTypeCategoryNameCompletion, request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp
index ce4662930a7c..e7b1f31f3960 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp
@@ -292,6 +292,14 @@ public:
~CommandObjectWatchpointEnable() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion,
+ request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Target *target = &GetSelectedTarget();
@@ -362,6 +370,14 @@ public:
~CommandObjectWatchpointDisable() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion,
+ request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Target *target = &GetSelectedTarget();
@@ -439,6 +455,14 @@ public:
~CommandObjectWatchpointDelete() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion,
+ request, nullptr);
+ }
+
Options *GetOptions() override { return &m_options; }
class CommandOptions : public Options {
@@ -557,6 +581,14 @@ public:
~CommandObjectWatchpointIgnore() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion,
+ request, nullptr);
+ }
+
Options *GetOptions() override { return &m_options; }
class CommandOptions : public Options {
@@ -677,6 +709,14 @@ public:
~CommandObjectWatchpointModify() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion,
+ request, nullptr);
+ }
+
Options *GetOptions() override { return &m_options; }
class CommandOptions : public Options {
@@ -823,6 +863,16 @@ corresponding to the byte size of the data type.");
~CommandObjectWatchpointSetVariable() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex() != 0)
+ return;
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion,
+ request, nullptr);
+ }
+
Options *GetOptions() override { return &m_option_group; }
protected:
@@ -905,7 +955,7 @@ protected:
// We're in business.
// Find out the size of this variable.
size = m_option_watchpoint.watch_size == 0
- ? valobj_sp->GetByteSize()
+ ? valobj_sp->GetByteSize().getValueOr(0)
: m_option_watchpoint.watch_size;
}
compiler_type = valobj_sp->GetCompilerType();
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.cpp b/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
new file mode 100644
index 000000000000..4445457ca852
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
@@ -0,0 +1,147 @@
+//===-- CommandOptionsProcessLaunch.cpp -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandOptionsProcessLaunch.h"
+
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/OptionParser.h"
+#include "lldb/Interpreter/CommandCompletions.h"
+#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Platform.h"
+#include "lldb/Target/Target.h"
+
+#include "llvm/ADT/ArrayRef.h"
+
+using namespace llvm;
+using namespace lldb;
+using namespace lldb_private;
+
+#define LLDB_OPTIONS_process_launch
+#include "CommandOptions.inc"
+
+Status CommandOptionsProcessLaunch::SetOptionValue(
+ uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 's': // Stop at program entry point
+ launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
+ break;
+
+ case 'i': // STDIN for read only
+ {
+ FileAction action;
+ if (action.Open(STDIN_FILENO, FileSpec(option_arg), true, false))
+ launch_info.AppendFileAction(action);
+ break;
+ }
+
+ case 'o': // Open STDOUT for write only
+ {
+ FileAction action;
+ if (action.Open(STDOUT_FILENO, FileSpec(option_arg), false, true))
+ launch_info.AppendFileAction(action);
+ break;
+ }
+
+ case 'e': // STDERR for write only
+ {
+ FileAction action;
+ if (action.Open(STDERR_FILENO, FileSpec(option_arg), false, true))
+ launch_info.AppendFileAction(action);
+ break;
+ }
+
+ case 'P': // Process plug-in name
+ launch_info.SetProcessPluginName(option_arg);
+ break;
+
+ case 'n': // Disable STDIO
+ {
+ FileAction action;
+ const FileSpec dev_null(FileSystem::DEV_NULL);
+ if (action.Open(STDIN_FILENO, dev_null, true, false))
+ launch_info.AppendFileAction(action);
+ if (action.Open(STDOUT_FILENO, dev_null, false, true))
+ launch_info.AppendFileAction(action);
+ if (action.Open(STDERR_FILENO, dev_null, false, true))
+ launch_info.AppendFileAction(action);
+ break;
+ }
+
+ case 'w':
+ launch_info.SetWorkingDirectory(FileSpec(option_arg));
+ break;
+
+ case 't': // Open process in new terminal window
+ launch_info.GetFlags().Set(eLaunchFlagLaunchInTTY);
+ break;
+
+ case 'a': {
+ TargetSP target_sp =
+ execution_context ? execution_context->GetTargetSP() : TargetSP();
+ PlatformSP platform_sp =
+ target_sp ? target_sp->GetPlatform() : PlatformSP();
+ launch_info.GetArchitecture() =
+ Platform::GetAugmentedArchSpec(platform_sp.get(), option_arg);
+ } break;
+
+ case 'A': // Disable ASLR.
+ {
+ bool success;
+ const bool disable_aslr_arg =
+ OptionArgParser::ToBoolean(option_arg, true, &success);
+ if (success)
+ disable_aslr = disable_aslr_arg ? eLazyBoolYes : eLazyBoolNo;
+ else
+ error.SetErrorStringWithFormat(
+ "Invalid boolean value for disable-aslr option: '%s'",
+ option_arg.empty() ? "<null>" : option_arg.str().c_str());
+ break;
+ }
+
+ case 'X': // shell expand args.
+ {
+ bool success;
+ const bool expand_args =
+ OptionArgParser::ToBoolean(option_arg, true, &success);
+ if (success)
+ launch_info.SetShellExpandArguments(expand_args);
+ else
+ error.SetErrorStringWithFormat(
+ "Invalid boolean value for shell-expand-args option: '%s'",
+ option_arg.empty() ? "<null>" : option_arg.str().c_str());
+ break;
+ }
+
+ case 'c':
+ if (!option_arg.empty())
+ launch_info.SetShell(FileSpec(option_arg));
+ else
+ launch_info.SetShell(HostInfo::GetDefaultShell());
+ break;
+
+ case 'v':
+ launch_info.GetEnvironment().insert(option_arg);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized short option character '%c'",
+ short_option);
+ break;
+ }
+ return error;
+}
+
+llvm::ArrayRef<OptionDefinition> CommandOptionsProcessLaunch::GetDefinitions() {
+ return llvm::makeArrayRef(g_process_launch_options);
+}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.h b/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.h
new file mode 100644
index 000000000000..4028d8e02cb2
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.h
@@ -0,0 +1,49 @@
+//===-- CommandOptionsProcessLaunch.h -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_COMMANDS_COMMANDOPTIONSPROCESSLAUNCH_H
+#define LLDB_SOURCE_COMMANDS_COMMANDOPTIONSPROCESSLAUNCH_H
+
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Interpreter/Options.h"
+
+namespace lldb_private {
+
+// CommandOptionsProcessLaunch
+
+class CommandOptionsProcessLaunch : public lldb_private::Options {
+public:
+ CommandOptionsProcessLaunch() : lldb_private::Options() {
+ // Keep default values of all options in one place: OptionParsingStarting
+ // ()
+ OptionParsingStarting(nullptr);
+ }
+
+ ~CommandOptionsProcessLaunch() override = default;
+
+ lldb_private::Status
+ SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ lldb_private::ExecutionContext *execution_context) override;
+
+ void OptionParsingStarting(
+ lldb_private::ExecutionContext *execution_context) override {
+ launch_info.Clear();
+ disable_aslr = lldb_private::eLazyBoolCalculate;
+ }
+
+ llvm::ArrayRef<lldb_private::OptionDefinition> GetDefinitions() override;
+
+ // Instance variables to hold the values for command options.
+
+ lldb_private::ProcessLaunchInfo launch_info;
+ lldb_private::LazyBool disable_aslr;
+}; // CommandOptionsProcessLaunch
+
+}; // namespace lldb_private
+
+#endif // LLDB_SOURCE_COMMANDS_COMMANDOPTIONSPROCESSLAUNCH_H
diff --git a/contrib/llvm-project/lldb/source/Commands/Options.td b/contrib/llvm-project/lldb/source/Commands/Options.td
index d6f1e0a3c96d..d3329078893a 100644
--- a/contrib/llvm-project/lldb/source/Commands/Options.td
+++ b/contrib/llvm-project/lldb/source/Commands/Options.td
@@ -105,7 +105,7 @@ let Command = "breakpoint dummy" in {
let Command = "breakpoint set" in {
def breakpoint_set_shlib : Option<"shlib", "s">, Arg<"ShlibName">,
- Completion<"Module">, Groups<[1,2,3,4,5,6,7,8,9,11]>, // *not* in group 10
+ Completion<"Module">, Groups<[1,2,3,4,5,6,7,8,9,11,12]>, // *not* in group 10
Desc<"Set the breakpoint only in this shared library. Can repeat this "
"option multiple times to specify multiple shared libraries.">;
def breakpoint_set_hardware : Option<"hardware", "H">,
@@ -186,21 +186,24 @@ let Command = "breakpoint set" in {
"expression (note: currently only implemented for setting breakpoints on "
"identifiers). If not set the target.language setting is used.">;
def breakpoint_set_skip_prologue : Option<"skip-prologue", "K">,
- Arg<"Boolean">, Groups<[1,3,4,5,6,7,8]>,
+ Arg<"Boolean">, Groups<[1,3,4,5,6,7,8,12]>,
Desc<"sKip the prologue if the breakpoint is at the beginning of a "
"function. If not set the target.skip-prologue setting is used.">;
def breakpoint_set_breakpoint_name : Option<"breakpoint-name", "N">,
Arg<"BreakpointName">,
Desc<"Adds this to the list of names for this breakpoint.">;
def breakpoint_set_address_slide : Option<"address-slide", "R">,
- Arg<"Address">, Groups<[1,3,4,5,6,7,8]>,
+ Arg<"Address">, Groups<[1,3,4,5,6,7,8,12]>,
Desc<"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.">;
def breakpoint_set_move_to_nearest_code : Option<"move-to-nearest-code", "m">,
- Groups<[1, 9]>, Arg<"Boolean">,
+ Groups<[1,9,12]>, Arg<"Boolean">,
Desc<"Move breakpoints to nearest code. If not set the "
"target.move-to-nearest-codesetting is used.">;
+ def breakpoint_set_file_colon_line : Option<"joint-specifier", "y">, Group<12>, Arg<"FileLineColumn">,
+ Required, Completion<"SourceFile">,
+ Desc<"A specifier in the form filename:line[:column] for setting file & line breakpoints.">;
/* Don't add this option till it actually does something useful...
def breakpoint_set_exception_typename : Option<"exception-typename", "O">,
Arg<"TypeName">, Desc<"The breakpoint will only stop if an "
@@ -224,6 +227,9 @@ let Command = "breakpoint delete" in {
def breakpoint_delete_dummy_breakpoints : Option<"dummy-breakpoints", "D">,
Group<1>, Desc<"Delete Dummy breakpoints - i.e. breakpoints set before a "
"file is provided, which prime new targets.">;
+ def breakpoint_delete_disabled : Option<"disabled", "d">, Group<1>,
+ Desc<"Delete all breakpoints which are currently disabled. When using the disabled option "
+ "any breakpoints listed on the command line are EXCLUDED from deletion.">;
}
let Command = "breakpoint name" in {
@@ -321,7 +327,7 @@ let Command = "disassemble" in {
def disassemble_options_pc : Option<"pc", "p">, Group<5>,
Desc<"Disassemble around the current pc.">;
def disassemble_options_line : Option<"line", "l">, Group<6>,
- Desc<"Disassemble the current frame's current source line instructions if"
+ Desc<"Disassemble the current frame's current source line instructions if "
"there is debug line table information, else disassemble around the pc.">;
def disassemble_options_address : Option<"address", "a">, Group<7>,
Arg<"AddressOrExpression">,
@@ -366,7 +372,7 @@ let Command = "expression" in {
"top-level entities without a $ prefix.">;
def expression_options_allow_jit : Option<"allow-jit", "j">, Groups<[1,2]>,
Arg<"Boolean">,
- Desc<"Controls whether the expression can fall back to being JITted if it's"
+ Desc<"Controls whether the expression can fall back to being JITted if it's "
"not supported by the interpreter (defaults to true).">;
}
@@ -448,6 +454,12 @@ let Command = "reproducer dump" in {
"provided, that reproducer is dumped.">;
}
+let Command = "reproducer verify" in {
+ def reproducer_verify_file : Option<"file", "f">, Group<1>, Arg<"Filename">,
+ Desc<"The reproducer path. If a reproducer is replayed and no path is "
+ "provided, that reproducer is dumped.">;
+}
+
let Command = "reproducer xcrash" in {
def reproducer_signal : Option<"signal", "s">, Group<1>,
EnumArg<"None", "ReproducerSignalType()">,
@@ -628,6 +640,39 @@ let Command = "platform shell" in {
Desc<"Run the commands on the host shell when enabled.">;
def platform_shell_timeout : Option<"timeout", "t">, Arg<"Value">,
Desc<"Seconds to wait for the remote host to finish running the command.">;
+ def platform_shell_interpreter : Option<"shell", "s">, Arg<"Path">,
+ Desc<"Shell interpreter path. This is the binary used to run the command.">;
+}
+
+let Command = "process launch" in {
+ def process_launch_stop_at_entry : Option<"stop-at-entry", "s">,
+ Desc<"Stop at the entry point of the program when launching a process.">;
+ def process_launch_disable_aslr : Option<"disable-aslr", "A">, Arg<"Boolean">,
+ Desc<"Set whether to disable address space layout randomization when launching a process.">;
+ def process_launch_plugin : Option<"plugin", "P">, Arg<"Plugin">,
+ Desc<"Name of the process plugin you want to use.">;
+ def process_launch_working_dir : Option<"working-dir", "w">, Arg<"DirectoryName">,
+ Desc<"Set the current working directory to <path> when running the inferior.">;
+ def process_launch_arch : Option<"arch", "a">, Arg<"Architecture">,
+ Desc<"Set the architecture for the process to launch when ambiguous.">;
+ def process_launch_environment : Option<"environment", "v">,
+ Arg<"None">, Desc<"Specify an environment variable name/value string "
+ "(--environment NAME=VALUE). Can be specified multiple times for subsequent "
+ "environment entries.">;
+ def process_launch_shell : Option<"shell", "c">, GroupRange<1,3>,
+ OptionalArg<"Filename">, Desc<"Run the process in a shell (not supported on all platforms).">;
+ def process_launch_stdin : Option<"stdin", "i">, Group<1>,
+ Arg<"Filename">, Desc<"Redirect stdin for the process to <filename>.">;
+ def process_launch_stdout : Option<"stdout", "o">, Group<1>,
+ Arg<"Filename">, Desc<"Redirect stdout for the process to <filename>.">;
+ def process_launch_stderr : Option<"stderr", "e">, Group<1>,
+ Arg<"Filename">, Desc<"Redirect stderr for the process to <filename>.">;
+ def process_launch_tty : Option<"tty", "t">, Group<2>,
+ Desc<"Start the process in a terminal (not supported on all platforms).">;
+ def process_launch_no_stdio : Option<"no-stdio", "n">, Group<3>,
+ Desc<"Do not set up for terminal I/O to go to running process.">;
+ def process_launch_shell_expand_args : Option<"shell-expand-args", "X">, Group<4>,
+ Arg<"Boolean">, Desc<"Set whether to shell expand arguments to the process when launching.">;
}
let Command = "process attach" in {
@@ -690,6 +735,10 @@ let Command = "script import" in {
Desc<"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.">;
+ def relative_to_command_file : Option<"relative-to-command-file", "c">,
+ Group<1>, Desc<"Resolve non-absolute paths relative to the location of the "
+ "current command file. This argument can only be used when the command is "
+ "being sourced from a file.">;
}
let Command = "script add" in {
@@ -706,6 +755,12 @@ let Command = "script add" in {
"LLDB event system.">;
}
+let Command = "script" in {
+ def script_language : Option<"language", "l">,
+ EnumArg<"ScriptLang", "ScriptOptionEnum()">, Desc<"Specify the scripting "
+ " language. If none is specific the default scripting language is used.">;
+}
+
let Command = "source info" in {
def source_info_count : Option<"count", "c">, Arg<"Count">,
Desc<"The number of line entries to display.">;
@@ -729,7 +784,7 @@ let Command = "source info" in {
let Command = "source list" in {
def source_list_count : Option<"count", "c">, Arg<"Count">,
Desc<"The number of source lines to display.">;
- def source_list_shlib : Option<"shlib", "s">, Groups<[1,2]>, Arg<"ShlibName">,
+ def source_list_shlib : Option<"shlib", "s">, Groups<[1,2,5]>, Arg<"ShlibName">,
Completion<"Module">,
Desc<"Look up the source file in the given shared library.">;
def source_list_show_breakpoints : Option<"show-breakpoints", "b">,
@@ -747,6 +802,10 @@ let Command = "source list" in {
" information for the corresponding file and line.">;
def source_list_reverse : Option<"reverse", "r">, Group<4>, Desc<"Reverse the"
" listing to look backwards from the last displayed block of source.">;
+ def source_list_file_colon_line : Option<"joint-specifier", "y">, Group<5>,
+ Arg<"FileLineColumn">, Completion<"SourceFile">,
+ Desc<"A specifier in the form filename:line[:column] from which to display"
+ " source.">;
}
let Command = "target dependents" in {
@@ -855,7 +914,7 @@ let Command = "target modules lookup" in {
}
let Command = "target stop hook add" in {
- def target_stop_hook_add_one_liner : Option<"one-liner", "o">,
+ def target_stop_hook_add_one_liner : Option<"one-liner", "o">, GroupRange<1,3>,
Arg<"OneLiner">, Desc<"Add a command for the stop hook. Can be specified "
"more than once, and commands will be run in the order they appear.">;
def target_stop_hook_add_shlib : Option<"shlib", "s">, Arg<"ShlibName">,
@@ -873,19 +932,19 @@ let Command = "target stop hook add" in {
def target_stop_hook_add_queue_name : Option<"queue-name", "q">,
Arg<"QueueName">, Desc<"The stop hook is run only for threads in the queue "
"whose name is given by this argument.">;
- def target_stop_hook_add_file : Option<"file", "f">, Group<1>,
+ def target_stop_hook_add_file : Option<"file", "f">, Groups<[1,4]>,
Arg<"Filename">, Desc<"Specify the source file within which the stop-hook "
"is to be run.">, Completion<"SourceFile">;
- def target_stop_hook_add_start_line : Option<"start-line", "l">, Group<1>,
+ def target_stop_hook_add_start_line : Option<"start-line", "l">, Groups<[1,4]>,
Arg<"LineNum">, Desc<"Set the start of the line range for which the "
"stop-hook is to be run.">;
- def target_stop_hook_add_end_line : Option<"end-line", "e">, Group<1>,
+ def target_stop_hook_add_end_line : Option<"end-line", "e">, Groups<[1,4]>,
Arg<"LineNum">, Desc<"Set the end of the line range for which the stop-hook"
" is to be run.">;
- def target_stop_hook_add_classname : Option<"classname", "c">, Group<2>,
+ def target_stop_hook_add_classname : Option<"classname", "c">, Groups<[2,5]>,
Arg<"ClassName">,
Desc<"Specify the class within which the stop-hook is to be run.">;
- def target_stop_hook_add_name : Option<"name", "n">, Group<3>,
+ def target_stop_hook_add_name : Option<"name", "n">, Groups<[3,6]>,
Arg<"FunctionName">, Desc<"Set the function name within which the stop hook"
" will be run.">, Completion<"Symbol">;
def target_stop_hook_add_auto_continue : Option<"auto-continue", "G">,
@@ -924,7 +983,7 @@ let Command = "thread step scope" in {
EnumArg<"RunMode", "TriRunningModes()">, Desc<"Determine how to run other "
"threads while stepping the current thread.">;
def thread_step_scope_step_over_regexp : Option<"step-over-regexp", "r">,
- Group<1>, Arg<"RegularExpression">, Desc<"A regular expression that defines"
+ Group<1>, Arg<"RegularExpression">, Desc<"A regular expression that defines "
"function names to not to stop at when stepping in.">;
def thread_step_scope_step_in_target : Option<"step-in-target", "t">,
Group<1>, Arg<"FunctionName">, Desc<"The name of the directly called "
@@ -937,10 +996,10 @@ let Command = "thread until" in {
def thread_until_thread : Option<"thread", "t">, Group<1>, Arg<"ThreadIndex">,
Desc<"Thread index for the thread for until operation">;
def thread_until_run_mode : Option<"run-mode", "m">, Group<1>,
- EnumArg<"RunMode", "DuoRunningModes()">, Desc<"Determine how to run other"
+ EnumArg<"RunMode", "DuoRunningModes()">, Desc<"Determine how to run other "
"threads while stepping this one">;
def thread_until_address : Option<"address", "a">, Group<1>,
- Arg<"AddressOrExpression">, Desc<"Run until we reach the specified address,"
+ Arg<"AddressOrExpression">, Desc<"Run until we reach the specified address, "
"or leave the function - can be specified multiple times.">;
}
@@ -981,6 +1040,19 @@ let Command = "thread plan list" in {
Desc<"Display thread plans for unreported threads">;
}
+let Command = "thread trace dump instructions" in {
+ def thread_trace_dump_instructions_count : Option<"count", "c">, Group<1>,
+ Arg<"Count">,
+ Desc<"The number of instructions to display ending at the current position.">;
+ def thread_trace_dump_instructions_position : Option<"position", "p">,
+ Group<1>,
+ Arg<"Index">,
+ Desc<"The position to use instead of the current position of the trace.">;
+ def thread_trace_dump_instructions_raw : Option<"raw", "r">,
+ Group<1>,
+ Desc<"Dump only instruction address without disassembly nor symbol information.">;
+}
+
let Command = "type summary add" in {
def type_summary_add_category : Option<"category", "w">, Arg<"Name">,
Desc<"Add this to the given category instead of the default one.">;
@@ -1117,7 +1189,7 @@ let Command = "watchpoint list" in {
"brief description of the watchpoint (no location info).">;
def watchpoint_list_full : Option<"full", "f">, Group<2>, Desc<"Give a full "
"description of the watchpoint and its locations.">;
- def watchpoint_list_verbose : Option<"verbose", "v">, Group<3>, Desc<"Explain"
+ def watchpoint_list_verbose : Option<"verbose", "v">, Group<3>, Desc<"Explain "
"everything we know about the watchpoint (for debugging debugger bugs).">;
}
@@ -1154,3 +1226,19 @@ let Command = "watchpoint delete" in {
def watchpoint_delete_force : Option<"force", "f">, Group<1>,
Desc<"Delete all watchpoints without querying for confirmation.">;
}
+
+let Command = "trace load" in {
+ def trace_load_verbose : Option<"verbose", "v">, Group<1>,
+ Desc<"Show verbose trace load logging for debugging the plug-in "
+ "implementation.">;
+}
+
+let Command = "trace dump" in {
+ def trace_dump_verbose : Option<"verbose", "v">, Group<1>,
+ Desc<"Show verbose trace information.">;
+}
+
+let Command = "trace schema" in {
+ def trace_schema_verbose : Option<"verbose", "v">, Group<1>,
+ Desc<"Show verbose trace schema logging for debugging the plug-in.">;
+}
diff --git a/contrib/llvm-project/lldb/source/Core/Communication.cpp b/contrib/llvm-project/lldb/source/Core/Communication.cpp
index b358e70b1a91..b50cd0ecab5c 100644
--- a/contrib/llvm-project/lldb/source/Core/Communication.cpp
+++ b/contrib/llvm-project/lldb/source/Core/Communication.cpp
@@ -199,9 +199,8 @@ bool Communication::StartReadThread(Status *error_ptr) {
LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION),
"{0} Communication::StartReadThread ()", this);
- char thread_name[1024];
- snprintf(thread_name, sizeof(thread_name), "<lldb.comm.%s>",
- GetBroadcasterName().AsCString());
+ const std::string thread_name =
+ llvm::formatv("<lldb.comm.{0}>", GetBroadcasterName());
m_read_thread_enabled = true;
m_read_thread_did_exit = false;
@@ -340,7 +339,7 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
}
if (error.Fail())
LLDB_LOG(log, "error: {0}, status = {1}", error,
- Communication::ConnectionStatusAsCString(status));
+ Communication::ConnectionStatusAsString(status));
break;
case eConnectionStatusInterrupted: // Synchronization signal from
// SynchronizeWithReadThread()
@@ -356,7 +355,7 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
case eConnectionStatusTimedOut: // Request timed out
if (error.Fail())
LLDB_LOG(log, "error: {0}, status = {1}", error,
- Communication::ConnectionStatusAsCString(status));
+ Communication::ConnectionStatusAsString(status));
break;
}
}
@@ -417,8 +416,8 @@ void Communication::SetConnection(std::unique_ptr<Connection> connection) {
m_connection_sp = std::move(connection);
}
-const char *
-Communication::ConnectionStatusAsCString(lldb::ConnectionStatus status) {
+std::string
+Communication::ConnectionStatusAsString(lldb::ConnectionStatus status) {
switch (status) {
case eConnectionStatusSuccess:
return "success";
@@ -436,8 +435,5 @@ Communication::ConnectionStatusAsCString(lldb::ConnectionStatus status) {
return "interrupted";
}
- static char unknown_state_string[64];
- snprintf(unknown_state_string, sizeof(unknown_state_string),
- "ConnectionStatus = %i", status);
- return unknown_state_string;
+ return "@" + std::to_string(status);
}
diff --git a/contrib/llvm-project/lldb/source/Core/CoreProperties.td b/contrib/llvm-project/lldb/source/Core/CoreProperties.td
index 8b05b126fe6f..f0653334c448 100644
--- a/contrib/llvm-project/lldb/source/Core/CoreProperties.td
+++ b/contrib/llvm-project/lldb/source/Core/CoreProperties.td
@@ -131,4 +131,8 @@ let Definition = "debugger" in {
Global,
DefaultStringValue<"frame #${frame.index}: ${ansi.fg.yellow}${frame.pc}${ansi.normal}{ ${module.file.basename}{`${function.name-without-args}{${frame.no-debug}${function.pc-offset}}}}{ at ${ansi.fg.cyan}${line.file.basename}${ansi.normal}:${ansi.fg.yellow}${line.number}${ansi.normal}{:${ansi.fg.yellow}${line.column}${ansi.normal}}}{${function.is-optimized} [opt]}{${frame.is-artificial} [artificial]}\\\\n">,
Desc<"The default frame format string to use when displaying stack frameinformation for threads from thread backtrace unique.">;
+ def ShowAutosuggestion: Property<"show-autosuggestion", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"If true, LLDB will show suggestions to complete the command the user typed.">;
}
diff --git a/contrib/llvm-project/lldb/source/Core/Debugger.cpp b/contrib/llvm-project/lldb/source/Core/Debugger.cpp
index 5f4f1e266d81..b16ce68c2fd2 100644
--- a/contrib/llvm-project/lldb/source/Core/Debugger.cpp
+++ b/contrib/llvm-project/lldb/source/Core/Debugger.cpp
@@ -346,6 +346,12 @@ bool Debugger::SetUseColor(bool b) {
return ret;
}
+bool Debugger::GetUseAutosuggestion() const {
+ const uint32_t idx = ePropertyShowAutosuggestion;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_debugger_properties[idx].default_uint_value != 0);
+}
+
bool Debugger::GetUseSourceCache() const {
const uint32_t idx = ePropertyUseSourceCache;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
@@ -666,9 +672,7 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton)
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());
- m_instance_name.SetCString(instance_cstr);
+ m_instance_name.SetString(llvm::formatv("debugger_{0}", GetID()).str());
if (log_callback)
m_log_callback_stream_sp =
std::make_shared<StreamCallback>(log_callback, baton);
@@ -678,7 +682,16 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton)
assert(default_platform_sp);
m_platform_list.Append(default_platform_sp, true);
- m_dummy_target_sp = m_target_list.GetDummyTarget(*this);
+ // Create the dummy target.
+ {
+ ArchSpec arch(Target::GetDefaultArchitecture());
+ if (!arch.IsValid())
+ arch = HostInfo::GetArchitecture();
+ assert(arch.IsValid() && "No valid default or host archspec");
+ const bool is_dummy_target = true;
+ m_dummy_target_sp.reset(
+ new Target(*this, arch, default_platform_sp, is_dummy_target));
+ }
assert(m_dummy_target_sp.get() && "Couldn't construct dummy target?");
m_collection_sp->Initialize(g_debugger_properties);
@@ -778,7 +791,7 @@ repro::DataRecorder *Debugger::GetInputRecorder() { return m_input_recorder; }
void Debugger::SetInputFile(FileSP file_sp, repro::DataRecorder *recorder) {
assert(file_sp && file_sp->IsValid());
m_input_recorder = recorder;
- m_input_file_sp = file_sp;
+ m_input_file_sp = std::move(file_sp);
// Save away the terminal state if that is relevant, so that we can restore
// it in RestoreInputState.
SaveInputTerminalState();
@@ -1160,11 +1173,11 @@ bool Debugger::EnableLog(llvm::StringRef channel,
flags |= File::eOpenOptionAppend;
else
flags |= File::eOpenOptionTruncate;
- auto file = FileSystem::Instance().Open(
+ llvm::Expected<FileUP> file = FileSystem::Instance().Open(
FileSpec(log_file), flags, lldb::eFilePermissionsFileDefault, false);
if (!file) {
- // FIXME: This gets garbled when called from the log command.
- error_stream << "Unable to open log file: " << log_file;
+ error_stream << "Unable to open log file '" << log_file
+ << "': " << llvm::toString(file.takeError()) << "\n";
return false;
}
@@ -1565,14 +1578,11 @@ void Debugger::JoinIOHandlerThread() {
}
}
-Target *Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) {
- Target *target = nullptr;
+Target &Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) {
if (!prefer_dummy) {
- target = m_target_list.GetSelectedTarget().get();
- if (target)
- return target;
+ if (TargetSP target = m_target_list.GetSelectedTarget())
+ return *target;
}
-
return GetDummyTarget();
}
diff --git a/contrib/llvm-project/lldb/source/Core/Disassembler.cpp b/contrib/llvm-project/lldb/source/Core/Disassembler.cpp
index 4da823c7a243..3a975d9296f4 100644
--- a/contrib/llvm-project/lldb/source/Core/Disassembler.cpp
+++ b/contrib/llvm-project/lldb/source/Core/Disassembler.cpp
@@ -58,9 +58,7 @@ using namespace lldb_private;
DisassemblerSP Disassembler::FindPlugin(const ArchSpec &arch,
const char *flavor,
const char *plugin_name) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat,
- "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
+ LLDB_SCOPED_TIMERF("Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
arch.GetArchitectureName(), plugin_name);
DisassemblerCreateInstance create_callback = nullptr;
@@ -540,34 +538,29 @@ void Disassembler::PrintInstructions(Debugger &debugger, const ArchSpec &arch,
}
bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
- const char *plugin_name, const char *flavor,
- const ExecutionContext &exe_ctx,
- uint32_t num_instructions,
- bool mixed_source_and_assembly,
- uint32_t num_mixed_context_lines,
- uint32_t options, Stream &strm) {
+ StackFrame &frame, Stream &strm) {
AddressRange range;
- StackFrame *frame = exe_ctx.GetFramePtr();
- if (frame) {
- SymbolContext sc(
- frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
- if (sc.function) {
- range = sc.function->GetAddressRange();
- } else if (sc.symbol && sc.symbol->ValueIsAddress()) {
- range.GetBaseAddress() = sc.symbol->GetAddressRef();
- range.SetByteSize(sc.symbol->GetByteSize());
- } else {
- range.GetBaseAddress() = frame->GetFrameCodeAddress();
- }
+ SymbolContext sc(
+ frame.GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
+ if (sc.function) {
+ range = sc.function->GetAddressRange();
+ } else if (sc.symbol && sc.symbol->ValueIsAddress()) {
+ range.GetBaseAddress() = sc.symbol->GetAddressRef();
+ range.SetByteSize(sc.symbol->GetByteSize());
+ } else {
+ range.GetBaseAddress() = frame.GetFrameCodeAddress();
+ }
if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
- }
- return Disassemble(
- debugger, arch, plugin_name, flavor, exe_ctx, range.GetBaseAddress(),
- {Limit::Instructions, num_instructions}, mixed_source_and_assembly,
- num_mixed_context_lines, options, strm);
+ Disassembler::Limit limit = {Disassembler::Limit::Bytes,
+ range.GetByteSize()};
+ if (limit.value == 0)
+ limit.value = DEFAULT_DISASM_BYTE_SIZE;
+
+ return Disassemble(debugger, arch, nullptr, nullptr, frame,
+ range.GetBaseAddress(), limit, false, 0, 0, strm);
}
Instruction::Instruction(const Address &address, AddressClass addr_class)
@@ -957,6 +950,13 @@ InstructionSP InstructionList::GetInstructionAtIndex(size_t idx) const {
return inst_sp;
}
+InstructionSP InstructionList::GetInstructionAtAddress(const Address &address) {
+ uint32_t index = GetIndexOfInstructionAtAddress(address);
+ if (index != UINT32_MAX)
+ return GetInstructionAtIndex(index);
+ return nullptr;
+}
+
void InstructionList::Dump(Stream *s, bool show_address, bool show_bytes,
const ExecutionContext *exe_ctx) {
const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
@@ -990,17 +990,15 @@ void InstructionList::Append(lldb::InstructionSP &inst_sp) {
uint32_t
InstructionList::GetIndexOfNextBranchInstruction(uint32_t start,
- Target &target,
bool ignore_calls,
bool *found_calls) const {
size_t num_instructions = m_instructions.size();
uint32_t next_branch = UINT32_MAX;
- size_t i;
if (found_calls)
*found_calls = false;
- for (i = start; i < num_instructions; i++) {
+ for (size_t i = start; i < num_instructions; i++) {
if (m_instructions[i]->DoesBranch()) {
if (ignore_calls && m_instructions[i]->IsCall()) {
if (found_calls)
@@ -1012,42 +1010,6 @@ InstructionList::GetIndexOfNextBranchInstruction(uint32_t start,
}
}
- // Hexagon needs the first instruction of the packet with the branch. Go
- // backwards until we find an instruction marked end-of-packet, or until we
- // hit start.
- if (target.GetArchitecture().GetTriple().getArch() == llvm::Triple::hexagon) {
- // If we didn't find a branch, find the last packet start.
- if (next_branch == UINT32_MAX) {
- i = num_instructions - 1;
- }
-
- while (i > start) {
- --i;
-
- Status error;
- uint32_t inst_bytes;
- bool prefer_file_cache = false; // Read from process if process is running
- lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
- target.ReadMemory(m_instructions[i]->GetAddress(), prefer_file_cache,
- &inst_bytes, sizeof(inst_bytes), error, &load_addr);
- // If we have an error reading memory, return start
- if (!error.Success())
- return start;
- // check if this is the last instruction in a packet bits 15:14 will be
- // 11b or 00b for a duplex
- if (((inst_bytes & 0xC000) == 0xC000) ||
- ((inst_bytes & 0xC000) == 0x0000)) {
- // instruction after this should be the start of next packet
- next_branch = i + 1;
- break;
- }
- }
-
- if (next_branch == UINT32_MAX) {
- // We couldn't find the previous packet, so return start
- next_branch = start;
- }
- }
return next_branch;
}
diff --git a/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp b/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp
index ceccbe437e1d..22cb9f18147a 100644
--- a/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp
+++ b/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp
@@ -60,8 +60,6 @@ DynamicLoader *DynamicLoader::FindPlugin(Process *process,
DynamicLoader::DynamicLoader(Process *process) : m_process(process) {}
-DynamicLoader::~DynamicLoader() = default;
-
// Accessosors to the global setting as to whether to stop at image (shared
// library) loading/unloading.
diff --git a/contrib/llvm-project/lldb/source/Core/IOHandler.cpp b/contrib/llvm-project/lldb/source/Core/IOHandler.cpp
index 6cf09aaa7f9d..8c654d9d8a98 100644
--- a/contrib/llvm-project/lldb/source/Core/IOHandler.cpp
+++ b/contrib/llvm-project/lldb/source/Core/IOHandler.cpp
@@ -18,6 +18,7 @@
#include "lldb/Host/Config.h"
#include "lldb/Host/File.h"
#include "lldb/Utility/Predicate.h"
+#include "lldb/Utility/ReproducerProvider.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StringList.h"
@@ -102,11 +103,11 @@ FILE *IOHandler::GetErrorFILE() {
return (m_error_sp ? m_error_sp->GetFile().GetStream() : nullptr);
}
-FileSP &IOHandler::GetInputFileSP() { return m_input_sp; }
+FileSP IOHandler::GetInputFileSP() { return m_input_sp; }
-StreamFileSP &IOHandler::GetOutputStreamFileSP() { return m_output_sp; }
+StreamFileSP IOHandler::GetOutputStreamFileSP() { return m_output_sp; }
-StreamFileSP &IOHandler::GetErrorStreamFileSP() { return m_error_sp; }
+StreamFileSP IOHandler::GetErrorStreamFileSP() { return m_error_sp; }
bool IOHandler::GetIsInteractive() {
return GetInputFileSP() ? GetInputFileSP()->GetIsInteractive() : false;
@@ -195,6 +196,14 @@ void IOHandlerConfirm::IOHandlerInputComplete(IOHandler &io_handler,
}
}
+llvm::Optional<std::string>
+IOHandlerDelegate::IOHandlerSuggestion(IOHandler &io_handler,
+ llvm::StringRef line) {
+ return io_handler.GetDebugger()
+ .GetCommandInterpreter()
+ .GetAutoSuggestionForCommand(line);
+}
+
void IOHandlerDelegate::IOHandlerComplete(IOHandler &io_handler,
CompletionRequest &request) {
switch (m_completion) {
@@ -258,6 +267,8 @@ IOHandlerEditline::IOHandlerEditline(
m_color_prompts);
m_editline_up->SetIsInputCompleteCallback(IsInputCompleteCallback, this);
m_editline_up->SetAutoCompleteCallback(AutoCompleteCallback, this);
+ if (debugger.GetUseAutosuggestion() && debugger.GetUseColor())
+ m_editline_up->SetSuggestionCallback(SuggestionCallback, this);
// See if the delegate supports fixing indentation
const char *indent_chars = delegate.IOHandlerGetFixIndentationCharacters();
if (indent_chars) {
@@ -430,6 +441,16 @@ int IOHandlerEditline::FixIndentationCallback(Editline *editline,
*editline_reader, lines, cursor_position);
}
+llvm::Optional<std::string>
+IOHandlerEditline::SuggestionCallback(llvm::StringRef line, void *baton) {
+ IOHandlerEditline *editline_reader = static_cast<IOHandlerEditline *>(baton);
+ if (editline_reader)
+ return editline_reader->m_delegate.IOHandlerSuggestion(*editline_reader,
+ line);
+
+ return llvm::None;
+}
+
void IOHandlerEditline::AutoCompleteCallback(CompletionRequest &request,
void *baton) {
IOHandlerEditline *editline_reader = (IOHandlerEditline *)baton;
diff --git a/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp b/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp
index f8fc91772198..19066e6be623 100644
--- a/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp
+++ b/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp
@@ -10,9 +10,14 @@
#include "lldb/Host/Config.h"
#if LLDB_ENABLE_CURSES
+#if CURSES_HAVE_NCURSES_CURSES_H
+#include <ncurses/curses.h>
+#include <ncurses/panel.h>
+#else
#include <curses.h>
#include <panel.h>
#endif
+#endif
#if defined(__APPLE__)
#include <deque>
@@ -268,6 +273,32 @@ struct KeyHelp {
const char *description;
};
+// COLOR_PAIR index names
+enum {
+ // First 16 colors are 8 black background and 8 blue background colors,
+ // needed by OutputColoredStringTruncated().
+ BlackOnBlack = 1,
+ RedOnBlack,
+ GreenOnBlack,
+ YellowOnBlack,
+ BlueOnBlack,
+ MagentaOnBlack,
+ CyanOnBlack,
+ WhiteOnBlack,
+ BlackOnBlue,
+ RedOnBlue,
+ GreenOnBlue,
+ YellowOnBlue,
+ BlueOnBlue,
+ MagentaOnBlue,
+ CyanOnBlue,
+ WhiteOnBlue,
+ // Other colors, as needed.
+ BlackOnWhite,
+ MagentaOnWhite,
+ LastColorPairIndex = MagentaOnWhite
+};
+
class WindowDelegate {
public:
virtual ~WindowDelegate() = default;
@@ -362,23 +393,23 @@ public:
}
void Clear() { ::wclear(m_window); }
void Erase() { ::werase(m_window); }
- Rect GetBounds() {
+ Rect GetBounds() const {
return Rect(GetParentOrigin(), GetSize());
} // Get the rectangle in our parent window
int GetChar() { return ::wgetch(m_window); }
- int GetCursorX() { return getcurx(m_window); }
- int GetCursorY() { return getcury(m_window); }
- Rect GetFrame() {
+ int GetCursorX() const { return getcurx(m_window); }
+ int GetCursorY() const { return getcury(m_window); }
+ Rect GetFrame() const {
return Rect(Point(), GetSize());
} // Get our rectangle in our own coordinate system
- Point GetParentOrigin() { return Point(GetParentX(), GetParentY()); }
- Size GetSize() { return Size(GetWidth(), GetHeight()); }
- int GetParentX() { return getparx(m_window); }
- int GetParentY() { return getpary(m_window); }
- int GetMaxX() { return getmaxx(m_window); }
- int GetMaxY() { return getmaxy(m_window); }
- int GetWidth() { return GetMaxX(); }
- int GetHeight() { return GetMaxY(); }
+ Point GetParentOrigin() const { return Point(GetParentX(), GetParentY()); }
+ Size GetSize() const { return Size(GetWidth(), GetHeight()); }
+ int GetParentX() const { return getparx(m_window); }
+ int GetParentY() const { return getpary(m_window); }
+ int GetMaxX() const { return getmaxx(m_window); }
+ int GetMaxY() const { return getmaxy(m_window); }
+ int GetWidth() const { return GetMaxX(); }
+ int GetHeight() const { return GetMaxY(); }
void MoveCursor(int x, int y) { ::wmove(m_window, y, x); }
void MoveWindow(int x, int y) { MoveWindow(Point(x, y)); }
void Resize(int w, int h) { ::wresize(m_window, h, w); }
@@ -391,11 +422,11 @@ public:
::wbkgd(m_window, COLOR_PAIR(color_pair_idx));
}
- void PutCStringTruncated(const char *s, int right_pad) {
+ void PutCStringTruncated(int right_pad, const char *s, int len = -1) {
int bytes_left = GetWidth() - GetCursorX();
if (bytes_left > right_pad) {
bytes_left -= right_pad;
- ::waddnstr(m_window, s, bytes_left);
+ ::waddnstr(m_window, s, len < 0 ? bytes_left : std::min(bytes_left, len));
}
}
@@ -433,6 +464,93 @@ public:
va_end(args);
}
+ void PrintfTruncated(int right_pad, const char *format, ...)
+ __attribute__((format(printf, 3, 4))) {
+ va_list args;
+ va_start(args, format);
+ StreamString strm;
+ strm.PrintfVarArg(format, args);
+ va_end(args);
+ PutCStringTruncated(right_pad, strm.GetData());
+ }
+
+ size_t LimitLengthToRestOfLine(size_t length) const {
+ return std::min<size_t>(length, std::max(0, GetWidth() - GetCursorX() - 1));
+ }
+
+ // Curses doesn't allow direct output of color escape sequences, but that's
+ // how we get source lines from the Highligher class. Read the line and
+ // convert color escape sequences to curses color attributes. Use
+ // first_skip_count to skip leading visible characters. Returns false if all
+ // visible characters were skipped due to first_skip_count.
+ bool OutputColoredStringTruncated(int right_pad, StringRef string,
+ size_t skip_first_count,
+ bool use_blue_background) {
+ attr_t saved_attr;
+ short saved_pair;
+ bool result = false;
+ wattr_get(m_window, &saved_attr, &saved_pair, nullptr);
+ if (use_blue_background)
+ ::wattron(m_window, COLOR_PAIR(WhiteOnBlue));
+ while (!string.empty()) {
+ size_t esc_pos = string.find('\x1b');
+ if (esc_pos == StringRef::npos) {
+ string = string.substr(skip_first_count);
+ if (!string.empty()) {
+ PutCStringTruncated(right_pad, string.data(), string.size());
+ result = true;
+ }
+ break;
+ }
+ if (esc_pos > 0) {
+ if (skip_first_count > 0) {
+ int skip = std::min(esc_pos, skip_first_count);
+ string = string.substr(skip);
+ skip_first_count -= skip;
+ esc_pos -= skip;
+ }
+ if (esc_pos > 0) {
+ PutCStringTruncated(right_pad, string.data(), esc_pos);
+ result = true;
+ string = string.drop_front(esc_pos);
+ }
+ }
+ bool consumed = string.consume_front("\x1b");
+ assert(consumed);
+ UNUSED_IF_ASSERT_DISABLED(consumed);
+ // This is written to match our Highlighter classes, which seem to
+ // generate only foreground color escape sequences. If necessary, this
+ // will need to be extended.
+ if (!string.consume_front("[")) {
+ llvm::errs() << "Missing '[' in color escape sequence.\n";
+ continue;
+ }
+ // Only 8 basic foreground colors and reset, our Highlighter doesn't use
+ // anything else.
+ int value;
+ if (!!string.consumeInteger(10, value) || // Returns false on success.
+ !(value == 0 || (value >= 30 && value <= 37))) {
+ llvm::errs() << "No valid color code in color escape sequence.\n";
+ continue;
+ }
+ if (!string.consume_front("m")) {
+ llvm::errs() << "Missing 'm' in color escape sequence.\n";
+ continue;
+ }
+ if (value == 0) { // Reset.
+ wattr_set(m_window, saved_attr, saved_pair, nullptr);
+ if (use_blue_background)
+ ::wattron(m_window, COLOR_PAIR(WhiteOnBlue));
+ } else {
+ // Mapped directly to first 16 color pairs (black/blue background).
+ ::wattron(m_window,
+ COLOR_PAIR(value - 30 + 1 + (use_blue_background ? 8 : 0)));
+ }
+ }
+ wattr_set(m_window, saved_attr, saved_pair, nullptr);
+ return result;
+ }
+
void Touch() {
::touchwin(m_window);
if (m_parent)
@@ -521,7 +639,7 @@ public:
void DrawTitleBox(const char *title, const char *bottom_message = nullptr) {
attr_t attr = 0;
if (IsActive())
- attr = A_BOLD | COLOR_PAIR(2);
+ attr = A_BOLD | COLOR_PAIR(BlackOnWhite);
else
attr = 0;
if (attr)
@@ -548,7 +666,7 @@ public:
} else {
MoveCursor(1, GetHeight() - 1);
PutChar('[');
- PutCStringTruncated(bottom_message, 1);
+ PutCStringTruncated(1, bottom_message);
}
}
if (attr)
@@ -687,42 +805,44 @@ public:
void SelectNextWindowAsActive() {
// Move active focus to next window
- const size_t num_subwindows = m_subwindows.size();
- if (m_curr_active_window_idx == UINT32_MAX) {
- uint32_t idx = 0;
- for (auto subwindow_sp : m_subwindows) {
- if (subwindow_sp->GetCanBeActive()) {
- m_curr_active_window_idx = idx;
- break;
- }
- ++idx;
- }
- } else if (m_curr_active_window_idx + 1 < num_subwindows) {
- bool handled = false;
+ const int num_subwindows = m_subwindows.size();
+ int start_idx = 0;
+ if (m_curr_active_window_idx != UINT32_MAX) {
m_prev_active_window_idx = m_curr_active_window_idx;
- for (size_t idx = m_curr_active_window_idx + 1; idx < num_subwindows;
- ++idx) {
- if (m_subwindows[idx]->GetCanBeActive()) {
- m_curr_active_window_idx = idx;
- handled = true;
- break;
- }
+ start_idx = m_curr_active_window_idx + 1;
+ }
+ for (int idx = start_idx; idx < num_subwindows; ++idx) {
+ if (m_subwindows[idx]->GetCanBeActive()) {
+ m_curr_active_window_idx = idx;
+ return;
}
- if (!handled) {
- for (size_t idx = 0; idx <= m_prev_active_window_idx; ++idx) {
- if (m_subwindows[idx]->GetCanBeActive()) {
- m_curr_active_window_idx = idx;
- break;
- }
- }
+ }
+ for (int idx = 0; idx < start_idx; ++idx) {
+ if (m_subwindows[idx]->GetCanBeActive()) {
+ m_curr_active_window_idx = idx;
+ break;
}
- } else {
+ }
+ }
+
+ void SelectPreviousWindowAsActive() {
+ // Move active focus to previous window
+ const int num_subwindows = m_subwindows.size();
+ int start_idx = num_subwindows - 1;
+ if (m_curr_active_window_idx != UINT32_MAX) {
m_prev_active_window_idx = m_curr_active_window_idx;
- for (size_t idx = 0; idx < num_subwindows; ++idx) {
- if (m_subwindows[idx]->GetCanBeActive()) {
- m_curr_active_window_idx = idx;
- break;
- }
+ start_idx = m_curr_active_window_idx - 1;
+ }
+ for (int idx = start_idx; idx >= 0; --idx) {
+ if (m_subwindows[idx]->GetCanBeActive()) {
+ m_curr_active_window_idx = idx;
+ return;
+ }
+ }
+ for (int idx = num_subwindows - 1; idx > start_idx; --idx) {
+ if (m_subwindows[idx]->GetCanBeActive()) {
+ m_curr_active_window_idx = idx;
+ break;
}
}
}
@@ -916,9 +1036,9 @@ void Menu::DrawMenuTitle(Window &window, bool highlight) {
} else {
const int shortcut_key = m_key_value;
bool underlined_shortcut = false;
- const attr_t hilgight_attr = A_REVERSE;
+ const attr_t highlight_attr = A_REVERSE;
if (highlight)
- window.AttributeOn(hilgight_attr);
+ window.AttributeOn(highlight_attr);
if (llvm::isPrint(shortcut_key)) {
size_t lower_pos = m_name.find(tolower(shortcut_key));
size_t upper_pos = m_name.find(toupper(shortcut_key));
@@ -945,18 +1065,18 @@ void Menu::DrawMenuTitle(Window &window, bool highlight) {
}
if (highlight)
- window.AttributeOff(hilgight_attr);
+ window.AttributeOff(highlight_attr);
if (m_key_name.empty()) {
if (!underlined_shortcut && llvm::isPrint(m_key_value)) {
- window.AttributeOn(COLOR_PAIR(3));
+ window.AttributeOn(COLOR_PAIR(MagentaOnWhite));
window.Printf(" (%c)", m_key_value);
- window.AttributeOff(COLOR_PAIR(3));
+ window.AttributeOff(COLOR_PAIR(MagentaOnWhite));
}
} else {
- window.AttributeOn(COLOR_PAIR(3));
+ window.AttributeOn(COLOR_PAIR(MagentaOnWhite));
window.Printf(" (%s)", m_key_name.c_str());
- window.AttributeOff(COLOR_PAIR(3));
+ window.AttributeOff(COLOR_PAIR(MagentaOnWhite));
}
}
}
@@ -968,7 +1088,7 @@ bool Menu::WindowDelegateDraw(Window &window, bool force) {
Menu::Type menu_type = GetType();
switch (menu_type) {
case Menu::Type::Bar: {
- window.SetBackground(2);
+ window.SetBackground(BlackOnWhite);
window.MoveCursor(0, 0);
for (size_t i = 0; i < num_submenus; ++i) {
Menu *menu = submenus[i].get();
@@ -988,7 +1108,7 @@ bool Menu::WindowDelegateDraw(Window &window, bool force) {
int cursor_x = 0;
int cursor_y = 0;
window.Erase();
- window.SetBackground(2);
+ window.SetBackground(BlackOnWhite);
window.Box();
for (size_t i = 0; i < num_submenus; ++i) {
const bool is_selected = (i == static_cast<size_t>(selected_idx));
@@ -1189,18 +1309,16 @@ public:
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());
debugger.EnableForwardEvents(listener_sp);
- bool update = true;
+ m_update_screen = true;
#if defined(__APPLE__)
std::deque<int> escape_chars;
#endif
while (!done) {
- if (update) {
+ if (m_update_screen) {
m_window_sp->Draw(false);
// All windows should be calling Window::DeferredRefresh() instead of
// Window::Refresh() so we can do a single update and avoid any screen
@@ -1212,7 +1330,7 @@ public:
m_window_sp->MoveCursor(0, 0);
doupdate();
- update = false;
+ m_update_screen = false;
}
#if defined(__APPLE__)
@@ -1274,7 +1392,7 @@ public:
if (broadcaster_class == broadcaster_class_process) {
debugger.GetCommandInterpreter().UpdateExecutionContext(
nullptr);
- update = true;
+ m_update_screen = true;
continue; // Don't get any key, just update our view
}
}
@@ -1286,9 +1404,13 @@ public:
switch (key_result) {
case eKeyHandled:
debugger.GetCommandInterpreter().UpdateExecutionContext(nullptr);
- update = true;
+ m_update_screen = true;
break;
case eKeyNotHandled:
+ if (ch == 12) { // Ctrl+L, force full redraw
+ redrawwin(m_window_sp->get());
+ m_update_screen = true;
+ }
break;
case eQuitApplication:
done = true;
@@ -1306,12 +1428,65 @@ public:
return m_window_sp;
}
+ void TerminalSizeChanged() {
+ ::endwin();
+ ::refresh();
+ Rect content_bounds = m_window_sp->GetFrame();
+ m_window_sp->SetBounds(content_bounds);
+ if (WindowSP menubar_window_sp = m_window_sp->FindSubWindow("Menubar"))
+ menubar_window_sp->SetBounds(content_bounds.MakeMenuBar());
+ if (WindowSP status_window_sp = m_window_sp->FindSubWindow("Status"))
+ status_window_sp->SetBounds(content_bounds.MakeStatusBar());
+
+ WindowSP source_window_sp = m_window_sp->FindSubWindow("Source");
+ WindowSP variables_window_sp = m_window_sp->FindSubWindow("Variables");
+ WindowSP registers_window_sp = m_window_sp->FindSubWindow("Registers");
+ WindowSP threads_window_sp = m_window_sp->FindSubWindow("Threads");
+
+ Rect threads_bounds;
+ Rect source_variables_bounds;
+ content_bounds.VerticalSplitPercentage(0.80, source_variables_bounds,
+ threads_bounds);
+ if (threads_window_sp)
+ threads_window_sp->SetBounds(threads_bounds);
+ else
+ source_variables_bounds = content_bounds;
+
+ Rect source_bounds;
+ Rect variables_registers_bounds;
+ source_variables_bounds.HorizontalSplitPercentage(
+ 0.70, source_bounds, variables_registers_bounds);
+ if (variables_window_sp || registers_window_sp) {
+ if (variables_window_sp && registers_window_sp) {
+ Rect variables_bounds;
+ Rect registers_bounds;
+ variables_registers_bounds.VerticalSplitPercentage(
+ 0.50, variables_bounds, registers_bounds);
+ variables_window_sp->SetBounds(variables_bounds);
+ registers_window_sp->SetBounds(registers_bounds);
+ } else if (variables_window_sp) {
+ variables_window_sp->SetBounds(variables_registers_bounds);
+ } else {
+ registers_window_sp->SetBounds(variables_registers_bounds);
+ }
+ } else {
+ source_bounds = source_variables_bounds;
+ }
+
+ source_window_sp->SetBounds(source_bounds);
+
+ touchwin(stdscr);
+ redrawwin(m_window_sp->get());
+ m_update_screen = true;
+ }
+
protected:
WindowSP m_window_sp;
WindowDelegates m_window_delegates;
SCREEN *m_screen;
FILE *m_in;
FILE *m_out;
+ bool m_update_screen = false;
};
} // namespace curses
@@ -1322,19 +1497,18 @@ struct Row {
ValueObjectManager value;
Row *parent;
// The process stop ID when the children were calculated.
- uint32_t children_stop_id;
- int row_idx;
- int x;
- int y;
+ uint32_t children_stop_id = 0;
+ int row_idx = 0;
+ int x = 1;
+ int y = 1;
bool might_have_children;
- bool expanded;
- bool calculated_children;
+ bool expanded = false;
+ bool calculated_children = false;
std::vector<Row> children;
Row(const ValueObjectSP &v, Row *p)
- : value(v, lldb::eDynamicDontRunTarget, true), parent(p), row_idx(0),
- x(1), y(1), might_have_children(v ? v->MightHaveChildren() : false),
- expanded(false), calculated_children(false), children() {}
+ : value(v, lldb::eDynamicDontRunTarget, true), parent(p),
+ might_have_children(v ? v->MightHaveChildren() : false) {}
size_t GetDepth() const {
if (parent)
@@ -1849,7 +2023,7 @@ public:
if (FormatEntity::Format(m_format, strm, &sc, &exe_ctx, nullptr,
nullptr, false, false)) {
int right_pad = 1;
- window.PutCStringTruncated(strm.GetString().str().c_str(), right_pad);
+ window.PutCStringTruncated(right_pad, strm.GetString().str().c_str());
}
}
}
@@ -1908,7 +2082,7 @@ public:
if (FormatEntity::Format(m_format, strm, nullptr, &exe_ctx, nullptr,
nullptr, false, false)) {
int right_pad = 1;
- window.PutCStringTruncated(strm.GetString().str().c_str(), right_pad);
+ window.PutCStringTruncated(right_pad, strm.GetString().str().c_str());
}
}
}
@@ -1998,7 +2172,7 @@ public:
if (FormatEntity::Format(m_format, strm, nullptr, &exe_ctx, nullptr,
nullptr, false, false)) {
int right_pad = 1;
- window.PutCStringTruncated(strm.GetString().str().c_str(), right_pad);
+ window.PutCStringTruncated(right_pad, strm.GetString().str().c_str());
}
}
}
@@ -2301,29 +2475,29 @@ protected:
window.AttributeOn(A_REVERSE);
if (type_name && type_name[0])
- window.Printf("(%s) ", type_name);
+ window.PrintfTruncated(1, "(%s) ", type_name);
if (name && name[0])
- window.PutCString(name);
+ window.PutCStringTruncated(1, name);
attr_t changd_attr = 0;
if (valobj->GetValueDidChange())
- changd_attr = COLOR_PAIR(5) | A_BOLD;
+ changd_attr = COLOR_PAIR(RedOnBlack) | A_BOLD;
if (value && value[0]) {
- window.PutCString(" = ");
+ window.PutCStringTruncated(1, " = ");
if (changd_attr)
window.AttributeOn(changd_attr);
- window.PutCString(value);
+ window.PutCStringTruncated(1, value);
if (changd_attr)
window.AttributeOff(changd_attr);
}
if (summary && summary[0]) {
- window.PutChar(' ');
+ window.PutCStringTruncated(1, " ");
if (changd_attr)
window.AttributeOn(changd_attr);
- window.PutCString(summary);
+ window.PutCStringTruncated(1, summary);
if (changd_attr)
window.AttributeOff(changd_attr);
}
@@ -2761,7 +2935,7 @@ bool HelpDialogDelegate::WindowDelegateDraw(Window &window, bool force) {
while (y <= max_y) {
window.MoveCursor(x, y);
window.PutCStringTruncated(
- m_text.GetStringAtIndex(m_first_visible_line + y - min_y), 1);
+ 1, m_text.GetStringAtIndex(m_first_visible_line + y - min_y));
++y;
}
return true;
@@ -2831,7 +3005,8 @@ public:
eMenuID_Process,
eMenuID_ProcessAttach,
- eMenuID_ProcessDetach,
+ eMenuID_ProcessDetachResume,
+ eMenuID_ProcessDetachSuspended,
eMenuID_ProcessLaunch,
eMenuID_ProcessContinue,
eMenuID_ProcessHalt,
@@ -2867,6 +3042,10 @@ public:
window.SelectNextWindowAsActive();
return eKeyHandled;
+ case KEY_BTAB:
+ window.SelectPreviousWindowAsActive();
+ return eKeyHandled;
+
case 'h':
window.CreateHelpSubwindow();
return eKeyHandled;
@@ -2891,6 +3070,7 @@ public:
KeyHelp *WindowDelegateGetKeyHelp() override {
static curses::KeyHelp g_source_view_key_help[] = {
{'\t', "Select next view"},
+ {KEY_BTAB, "Select previous view"},
{'h', "Show help dialog with view specific key bindings"},
{',', "Page up"},
{'.', "Page down"},
@@ -2976,13 +3156,15 @@ public:
}
return MenuActionResult::Handled;
- case eMenuID_ProcessDetach: {
+ case eMenuID_ProcessDetachResume:
+ case eMenuID_ProcessDetachSuspended: {
ExecutionContext exe_ctx =
m_debugger.GetCommandInterpreter().GetExecutionContext();
if (exe_ctx.HasProcessScope()) {
Process *process = exe_ctx.GetProcessPtr();
if (process && process->IsAlive())
- process->Detach(false);
+ process->Detach(menu.GetIdentifier() ==
+ eMenuID_ProcessDetachSuspended);
}
}
return MenuActionResult::Handled;
@@ -3072,7 +3254,7 @@ public:
new_registers_rect);
registers_window_sp->SetBounds(new_registers_rect);
} else {
- // No variables window, grab the bottom part of the source window
+ // No registers window, grab the bottom part of the source window
Rect new_source_rect;
source_bounds.HorizontalSplitPercentage(0.70, new_source_rect,
new_variables_rect);
@@ -3123,7 +3305,7 @@ public:
new_regs_rect);
variables_window_sp->SetBounds(new_vars_rect);
} else {
- // No registers window, grab the bottom part of the source window
+ // No variables window, grab the bottom part of the source window
Rect new_source_rect;
source_bounds.HorizontalSplitPercentage(0.70, new_source_rect,
new_regs_rect);
@@ -3169,7 +3351,7 @@ public:
Thread *thread = exe_ctx.GetThreadPtr();
StackFrame *frame = exe_ctx.GetFramePtr();
window.Erase();
- window.SetBackground(2);
+ window.SetBackground(BlackOnWhite);
window.MoveCursor(0, 0);
if (process) {
const StateType state = process->GetState();
@@ -3181,7 +3363,7 @@ public:
if (thread && FormatEntity::Format(m_format, strm, nullptr, &exe_ctx,
nullptr, nullptr, false, false)) {
window.MoveCursor(40, 0);
- window.PutCStringTruncated(strm.GetString().str().c_str(), 1);
+ window.PutCStringTruncated(1, strm.GetString().str().c_str());
}
window.MoveCursor(60, 0);
@@ -3214,7 +3396,8 @@ public:
m_disassembly_scope(nullptr), m_disassembly_sp(), m_disassembly_range(),
m_title(), m_line_width(4), m_selected_line(0), m_pc_line(0),
m_stop_id(0), m_frame_idx(UINT32_MAX), m_first_visible_line(0),
- m_min_x(0), m_min_y(0), m_max_x(0), m_max_y(0) {}
+ m_first_visible_column(0), m_min_x(0), m_min_y(0), m_max_x(0),
+ m_max_y(0) {}
~SourceFileWindowDelegate() override = default;
@@ -3231,19 +3414,21 @@ public:
{KEY_RETURN, "Run to selected line with one shot breakpoint"},
{KEY_UP, "Select previous source line"},
{KEY_DOWN, "Select next source line"},
+ {KEY_LEFT, "Scroll to the left"},
+ {KEY_RIGHT, "Scroll to the right"},
{KEY_PPAGE, "Page up"},
{KEY_NPAGE, "Page down"},
{'b', "Set breakpoint on selected source/disassembly line"},
{'c', "Continue process"},
- {'d', "Detach and resume process"},
{'D', "Detach with process suspended"},
{'h', "Show help dialog"},
- {'k', "Kill process"},
{'n', "Step over (source line)"},
{'N', "Step over (single instruction)"},
- {'o', "Step out"},
+ {'f', "Step out (finish)"},
{'s', "Step in (source line)"},
{'S', "Step in (single instruction)"},
+ {'u', "Frame up"},
+ {'d', "Frame down"},
{',', "Page up"},
{'.', "Page down"},
{'\0', nullptr}};
@@ -3407,7 +3592,7 @@ public:
window.AttributeOn(A_REVERSE);
window.MoveCursor(1, 1);
window.PutChar(' ');
- window.PutCStringTruncated(m_title.GetString().str().c_str(), 1);
+ window.PutCStringTruncated(1, m_title.GetString().str().c_str());
int x = window.GetCursorX();
if (x < window_width - 1) {
window.Printf("%*s", window_width - x - 1, "");
@@ -3441,7 +3626,7 @@ public:
}
const attr_t selected_highlight_attr = A_REVERSE;
- const attr_t pc_highlight_attr = COLOR_PAIR(1);
+ const attr_t pc_highlight_attr = COLOR_PAIR(BlackOnBlue);
for (size_t i = 0; i < num_visible_lines; ++i) {
const uint32_t curr_line = m_first_visible_line + i;
@@ -3460,7 +3645,7 @@ public:
highlight_attr = selected_highlight_attr;
if (bp_lines.find(curr_line + 1) != bp_lines.end())
- bp_attr = COLOR_PAIR(2);
+ bp_attr = COLOR_PAIR(BlackOnWhite);
if (bp_attr)
window.AttributeOn(bp_attr);
@@ -3479,10 +3664,21 @@ public:
if (highlight_attr)
window.AttributeOn(highlight_attr);
- const uint32_t line_len =
- m_file_sp->GetLineLength(curr_line + 1, false);
- if (line_len > 0)
- window.PutCString(m_file_sp->PeekLineData(curr_line + 1), line_len);
+
+ StreamString lineStream;
+ m_file_sp->DisplaySourceLines(curr_line + 1, {}, 0, 0, &lineStream);
+ StringRef line = lineStream.GetString();
+ if (line.endswith("\n"))
+ line = line.drop_back();
+ bool wasWritten = window.OutputColoredStringTruncated(
+ 1, line, m_first_visible_column, line_is_selected);
+ if (line_is_selected && !wasWritten) {
+ // Draw an empty space to show the selected line if empty,
+ // or draw '<' if nothing is visible because of scrolling too much
+ // to the right.
+ window.PutCStringTruncated(
+ 1, line.empty() && m_first_visible_column == 0 ? " " : "<");
+ }
if (is_pc_line && frame_sp &&
frame_sp->GetConcreteFrameIndex() == 0) {
@@ -3494,11 +3690,15 @@ public:
if (stop_description && stop_description[0]) {
size_t stop_description_len = strlen(stop_description);
int desc_x = window_width - stop_description_len - 16;
- window.Printf("%*s", desc_x - window.GetCursorX(), "");
- // window.MoveCursor(window_width - stop_description_len - 15,
- // line_y);
- window.Printf("<<< Thread %u: %s ", thread->GetIndexID(),
- stop_description);
+ if (desc_x - window.GetCursorX() > 0)
+ window.Printf("%*s", desc_x - window.GetCursorX(), "");
+ window.MoveCursor(window_width - stop_description_len - 16,
+ line_y);
+ const attr_t stop_reason_attr = COLOR_PAIR(WhiteOnBlue);
+ window.AttributeOn(stop_reason_attr);
+ window.PrintfTruncated(1, " <<< Thread %u: %s ",
+ thread->GetIndexID(), stop_description);
+ window.AttributeOff(stop_reason_attr);
}
} else {
window.Printf("%*s", window_width - window.GetCursorX() - 1, "");
@@ -3538,7 +3738,7 @@ public:
}
const attr_t selected_highlight_attr = A_REVERSE;
- const attr_t pc_highlight_attr = COLOR_PAIR(1);
+ const attr_t pc_highlight_attr = COLOR_PAIR(WhiteOnBlue);
StreamString strm;
@@ -3586,7 +3786,7 @@ public:
if (bp_file_addrs.find(inst->GetAddress().GetFileAddress()) !=
bp_file_addrs.end())
- bp_attr = COLOR_PAIR(2);
+ bp_attr = COLOR_PAIR(BlackOnWhite);
if (bp_attr)
window.AttributeOn(bp_attr);
@@ -3629,7 +3829,9 @@ public:
strm.Printf("%s", mnemonic);
int right_pad = 1;
- window.PutCStringTruncated(strm.GetData(), right_pad);
+ window.PutCStringTruncated(
+ right_pad,
+ strm.GetString().substr(m_first_visible_column).data());
if (is_pc_line && frame_sp &&
frame_sp->GetConcreteFrameIndex() == 0) {
@@ -3641,11 +3843,12 @@ public:
if (stop_description && stop_description[0]) {
size_t stop_description_len = strlen(stop_description);
int desc_x = window_width - stop_description_len - 16;
- window.Printf("%*s", desc_x - window.GetCursorX(), "");
- // window.MoveCursor(window_width - stop_description_len - 15,
- // line_y);
- window.Printf("<<< Thread %u: %s ", thread->GetIndexID(),
- stop_description);
+ if (desc_x - window.GetCursorX() > 0)
+ window.Printf("%*s", desc_x - window.GetCursorX(), "");
+ window.MoveCursor(window_width - stop_description_len - 15,
+ line_y);
+ window.PrintfTruncated(1, "<<< Thread %u: %s ",
+ thread->GetIndexID(), stop_description);
}
} else {
window.Printf("%*s", window_width - window.GetCursorX() - 1, "");
@@ -3723,6 +3926,15 @@ public:
}
return eKeyHandled;
+ case KEY_LEFT:
+ if (m_first_visible_column > 0)
+ --m_first_visible_column;
+ return eKeyHandled;
+
+ case KEY_RIGHT:
+ ++m_first_visible_column;
+ return eKeyHandled;
+
case '\r':
case '\n':
case KEY_ENTER:
@@ -3767,59 +3979,18 @@ public:
return eKeyHandled;
case 'b': // 'b' == toggle breakpoint on currently selected line
- if (m_selected_line < GetNumSourceLines()) {
- ExecutionContext exe_ctx =
- m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasTargetScope()) {
- 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 column specified.
- 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()) {
- const Instruction *inst = m_disassembly_sp->GetInstructionList()
- .GetInstructionAtIndex(m_selected_line)
- .get();
- ExecutionContext exe_ctx =
- m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasTargetScope()) {
- Address addr = inst->GetAddress();
- BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint(
- addr, // lldb_private::Address
- false, // internal
- false); // request_hardware
- }
- }
+ ToggleBreakpointOnSelectedLine();
return eKeyHandled;
- case 'd': // 'd' == detach and let run
case 'D': // 'D' == detach and keep stopped
{
ExecutionContext exe_ctx =
m_debugger.GetCommandInterpreter().GetExecutionContext();
if (exe_ctx.HasProcessScope())
- exe_ctx.GetProcessRef().Detach(c == 'D');
+ exe_ctx.GetProcessRef().Detach(true);
}
return eKeyHandled;
- case 'k':
- // 'k' == kill
- {
- ExecutionContext exe_ctx =
- m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasProcessScope())
- exe_ctx.GetProcessRef().Destroy(false);
- }
- return eKeyHandled;
-
case 'c':
// 'c' == continue
{
@@ -3830,8 +4001,8 @@ public:
}
return eKeyHandled;
- case 'o':
- // 'o' == step out
+ case 'f':
+ // 'f' == step out (finish)
{
ExecutionContext exe_ctx =
m_debugger.GetCommandInterpreter().GetExecutionContext();
@@ -3868,6 +4039,26 @@ public:
}
return eKeyHandled;
+ case 'u': // 'u' == frame up
+ case 'd': // 'd' == frame down
+ {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasThreadScope()) {
+ Thread *thread = exe_ctx.GetThreadPtr();
+ uint32_t frame_idx = thread->GetSelectedFrameIndex();
+ if (frame_idx == UINT32_MAX)
+ frame_idx = 0;
+ if (c == 'u' && frame_idx + 1 < thread->GetStackFrameCount())
+ ++frame_idx;
+ else if (c == 'd' && frame_idx > 0)
+ --frame_idx;
+ if (thread->SetSelectedFrameByIndex(frame_idx, true))
+ exe_ctx.SetFrameSP(thread->GetSelectedFrame());
+ }
+ }
+ return eKeyHandled;
+
case 'h':
window.CreateHelpSubwindow();
return eKeyHandled;
@@ -3878,6 +4069,85 @@ public:
return eKeyNotHandled;
}
+ void ToggleBreakpointOnSelectedLine() {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (!exe_ctx.HasTargetScope())
+ return;
+ if (GetNumSourceLines() > 0) {
+ // Source file breakpoint.
+ BreakpointList &bp_list = exe_ctx.GetTargetRef().GetBreakpointList();
+ const size_t num_bps = bp_list.GetSize();
+ for (size_t bp_idx = 0; bp_idx < num_bps; ++bp_idx) {
+ BreakpointSP bp_sp = bp_list.GetBreakpointAtIndex(bp_idx);
+ const size_t num_bps_locs = bp_sp->GetNumLocations();
+ for (size_t bp_loc_idx = 0; bp_loc_idx < num_bps_locs; ++bp_loc_idx) {
+ BreakpointLocationSP bp_loc_sp =
+ bp_sp->GetLocationAtIndex(bp_loc_idx);
+ LineEntry bp_loc_line_entry;
+ if (bp_loc_sp->GetAddress().CalculateSymbolContextLineEntry(
+ bp_loc_line_entry)) {
+ if (m_file_sp->GetFileSpec() == bp_loc_line_entry.file &&
+ m_selected_line + 1 == bp_loc_line_entry.line) {
+ bool removed =
+ exe_ctx.GetTargetRef().RemoveBreakpointByID(bp_sp->GetID());
+ assert(removed);
+ UNUSED_IF_ASSERT_DISABLED(removed);
+ return; // Existing breakpoint removed.
+ }
+ }
+ }
+ }
+ // No breakpoint found on the location, add it.
+ 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 column specified.
+ 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 {
+ // Disassembly breakpoint.
+ assert(GetNumDisassemblyLines() > 0);
+ assert(m_selected_line < GetNumDisassemblyLines());
+ const Instruction *inst = m_disassembly_sp->GetInstructionList()
+ .GetInstructionAtIndex(m_selected_line)
+ .get();
+ Address addr = inst->GetAddress();
+ // Try to find it.
+ BreakpointList &bp_list = exe_ctx.GetTargetRef().GetBreakpointList();
+ const size_t num_bps = bp_list.GetSize();
+ for (size_t bp_idx = 0; bp_idx < num_bps; ++bp_idx) {
+ BreakpointSP bp_sp = bp_list.GetBreakpointAtIndex(bp_idx);
+ const size_t num_bps_locs = bp_sp->GetNumLocations();
+ for (size_t bp_loc_idx = 0; bp_loc_idx < num_bps_locs; ++bp_loc_idx) {
+ BreakpointLocationSP bp_loc_sp =
+ bp_sp->GetLocationAtIndex(bp_loc_idx);
+ LineEntry bp_loc_line_entry;
+ const lldb::addr_t file_addr =
+ bp_loc_sp->GetAddress().GetFileAddress();
+ if (file_addr == addr.GetFileAddress()) {
+ bool removed =
+ exe_ctx.GetTargetRef().RemoveBreakpointByID(bp_sp->GetID());
+ assert(removed);
+ UNUSED_IF_ASSERT_DISABLED(removed);
+ return; // Existing breakpoint removed.
+ }
+ }
+ }
+ // No breakpoint found on the address, add it.
+ BreakpointSP bp_sp =
+ exe_ctx.GetTargetRef().CreateBreakpoint(addr, // lldb_private::Address
+ false, // internal
+ false); // request_hardware
+ }
+ }
+
protected:
typedef std::set<uint32_t> BreakpointLines;
typedef std::set<lldb::addr_t> BreakpointAddrs;
@@ -3896,6 +4166,7 @@ protected:
uint32_t m_stop_id;
uint32_t m_frame_idx;
int m_first_visible_line;
+ int m_first_visible_column;
int m_min_x;
int m_min_y;
int m_max_x;
@@ -3939,8 +4210,12 @@ void IOHandlerCursesGUI::Activate() {
ApplicationDelegate::eMenuID_Process));
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("Detach and resume", nullptr, 'd',
+ ApplicationDelegate::eMenuID_ProcessDetachResume)));
+ process_menu_sp->AddSubmenu(
+ MenuSP(new Menu("Detach suspended", nullptr, 's',
+ ApplicationDelegate::eMenuID_ProcessDetachSuspended)));
process_menu_sp->AddSubmenu(MenuSP(new Menu(
"Launch", nullptr, 'l', ApplicationDelegate::eMenuID_ProcessLaunch)));
process_menu_sp->AddSubmenu(MenuSP(new Menu(Menu::Type::Separator)));
@@ -4042,11 +4317,28 @@ void IOHandlerCursesGUI::Activate() {
main_window_sp->CreateHelpSubwindow();
}
- init_pair(1, COLOR_WHITE, COLOR_BLUE);
- init_pair(2, COLOR_BLACK, COLOR_WHITE);
- init_pair(3, COLOR_MAGENTA, COLOR_WHITE);
- init_pair(4, COLOR_MAGENTA, COLOR_BLACK);
- init_pair(5, COLOR_RED, COLOR_BLACK);
+ // All colors with black background.
+ init_pair(1, COLOR_BLACK, COLOR_BLACK);
+ init_pair(2, COLOR_RED, COLOR_BLACK);
+ init_pair(3, COLOR_GREEN, COLOR_BLACK);
+ init_pair(4, COLOR_YELLOW, COLOR_BLACK);
+ init_pair(5, COLOR_BLUE, COLOR_BLACK);
+ init_pair(6, COLOR_MAGENTA, COLOR_BLACK);
+ init_pair(7, COLOR_CYAN, COLOR_BLACK);
+ init_pair(8, COLOR_WHITE, COLOR_BLACK);
+ // All colors with blue background.
+ init_pair(9, COLOR_BLACK, COLOR_BLUE);
+ init_pair(10, COLOR_RED, COLOR_BLUE);
+ init_pair(11, COLOR_GREEN, COLOR_BLUE);
+ init_pair(12, COLOR_YELLOW, COLOR_BLUE);
+ init_pair(13, COLOR_BLUE, COLOR_BLUE);
+ init_pair(14, COLOR_MAGENTA, COLOR_BLUE);
+ init_pair(15, COLOR_CYAN, COLOR_BLUE);
+ init_pair(16, COLOR_WHITE, COLOR_BLUE);
+ // These must match the order in the color indexes enum.
+ init_pair(17, COLOR_BLACK, COLOR_WHITE);
+ init_pair(18, COLOR_MAGENTA, COLOR_WHITE);
+ static_assert(LastColorPairIndex == 18, "Color indexes do not match.");
}
}
@@ -4065,4 +4357,8 @@ bool IOHandlerCursesGUI::Interrupt() { return false; }
void IOHandlerCursesGUI::GotEOF() {}
+void IOHandlerCursesGUI::TerminalSizeChanged() {
+ m_app_ap->TerminalSizeChanged();
+}
+
#endif // LLDB_ENABLE_CURSES
diff --git a/contrib/llvm-project/lldb/source/Core/Mangled.cpp b/contrib/llvm-project/lldb/source/Core/Mangled.cpp
index 143ec8770bf4..627be94a303c 100644
--- a/contrib/llvm-project/lldb/source/Core/Mangled.cpp
+++ b/contrib/llvm-project/lldb/source/Core/Mangled.cpp
@@ -14,7 +14,6 @@
#include "lldb/Utility/Logging.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"
-#include "lldb/Utility/Timer.h"
#include "lldb/lldb-enumerations.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
@@ -227,12 +226,6 @@ static char *GetItaniumDemangledStr(const char *M) {
// makes use of ItaniumPartialDemangler's rich demangle info
bool Mangled::DemangleWithRichManglingInfo(
RichManglingContext &context, SkipMangledNameFn *skip_mangled_name) {
- // We need to generate and cache the demangled name.
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat,
- "Mangled::DemangleWithRichNameIndexInfo (m_mangled = %s)",
- m_mangled.GetCString());
-
// Others are not meant to arrive here. ObjC names or C's main() for example
// have their names stored in m_demangled, while m_mangled is empty.
assert(m_mangled);
@@ -298,11 +291,6 @@ ConstString Mangled::GetDemangledName() const {
// Check to make sure we have a valid mangled name and that we haven't
// already decoded our mangled name.
if (m_mangled && m_demangled.IsNull()) {
- // We need to generate and cache the demangled name.
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "Mangled::GetDemangledName (m_mangled = %s)",
- m_mangled.GetCString());
-
// Don't bother running anything that isn't mangled
const char *mangled_name = m_mangled.GetCString();
ManglingScheme mangling_scheme = GetManglingScheme(m_mangled.GetStringRef());
diff --git a/contrib/llvm-project/lldb/source/Core/Module.cpp b/contrib/llvm-project/lldb/source/Core/Module.cpp
index b76659ee3e07..1f9987c21658 100644
--- a/contrib/llvm-project/lldb/source/Core/Module.cpp
+++ b/contrib/llvm-project/lldb/source/Core/Module.cpp
@@ -419,8 +419,7 @@ void Module::DumpSymbolContext(Stream *s) {
size_t Module::GetNumCompileUnits() {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "Module::GetNumCompileUnits (module = %p)",
+ LLDB_SCOPED_TIMERF("Module::GetNumCompileUnits (module = %p)",
static_cast<void *>(this));
if (SymbolFile *symbols = GetSymbolFile())
return symbols->GetNumCompileUnits();
@@ -441,9 +440,7 @@ CompUnitSP Module::GetCompileUnitAtIndex(size_t index) {
bool Module::ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat,
- "Module::ResolveFileAddress (vm_addr = 0x%" PRIx64 ")",
+ LLDB_SCOPED_TIMERF("Module::ResolveFileAddress (vm_addr = 0x%" PRIx64 ")",
vm_addr);
SectionList *section_list = GetSectionList();
if (section_list)
@@ -594,9 +591,7 @@ uint32_t Module::ResolveSymbolContextsForFileSpec(
const FileSpec &file_spec, uint32_t line, bool check_inlines,
lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat,
- "Module::ResolveSymbolContextForFilePath (%s:%u, "
+ LLDB_SCOPED_TIMERF("Module::ResolveSymbolContextForFilePath (%s:%u, "
"check_inlines = %s, resolve_scope = 0x%8.8x)",
file_spec.GetPath().c_str(), line,
check_inlines ? "yes" : "no", resolve_scope);
@@ -940,8 +935,7 @@ void Module::FindTypes_Impl(
size_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
if (SymbolFile *symbols = GetSymbolFile())
symbols->FindTypes(name, parent_decl_ctx, max_matches,
searched_symbol_files, types);
@@ -1028,8 +1022,7 @@ void Module::FindTypes(
llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
if (SymbolFile *symbols = GetSymbolFile())
symbols->FindTypes(pattern, languages, searched_symbol_files, types);
}
@@ -1040,8 +1033,7 @@ SymbolFile *Module::GetSymbolFile(bool can_create, Stream *feedback_strm) {
if (!m_did_load_symfile.load() && can_create) {
ObjectFile *obj_file = GetObjectFile();
if (obj_file != nullptr) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
m_symfile_up.reset(
SymbolVendor::FindPlugin(shared_from_this(), feedback_strm));
m_did_load_symfile = true;
@@ -1244,8 +1236,7 @@ ObjectFile *Module::GetObjectFile() {
if (!m_did_load_objfile.load()) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
if (!m_did_load_objfile.load()) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "Module::GetObjectFile () module = %s",
+ LLDB_SCOPED_TIMERF("Module::GetObjectFile () module = %s",
GetFileSpec().GetFilename().AsCString(""));
lldb::offset_t data_offset = 0;
lldb::offset_t file_size = 0;
@@ -1312,9 +1303,8 @@ SectionList *Module::GetUnifiedSectionList() {
const Symbol *Module::FindFirstSymbolWithNameAndType(ConstString name,
SymbolType symbol_type) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat, "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
+ LLDB_SCOPED_TIMERF(
+ "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
name.AsCString(), symbol_type);
if (Symtab *symtab = GetSymtab())
return symtab->FindFirstSymbolWithNameAndType(
@@ -1342,9 +1332,7 @@ void Module::SymbolIndicesToSymbolContextList(
void Module::FindFunctionSymbols(ConstString name,
uint32_t name_type_mask,
SymbolContextList &sc_list) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat,
- "Module::FindSymbolsFunctions (name = %s, mask = 0x%8.8x)",
+ LLDB_SCOPED_TIMERF("Module::FindSymbolsFunctions (name = %s, mask = 0x%8.8x)",
name.AsCString(), name_type_mask);
if (Symtab *symtab = GetSymtab())
symtab->FindFunctionSymbols(name, name_type_mask, sc_list);
@@ -1355,10 +1343,8 @@ void Module::FindSymbolsWithNameAndType(ConstString name,
SymbolContextList &sc_list) {
// No need to protect this call using m_mutex all other method calls are
// already thread safe.
-
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat, "Module::FindSymbolsWithNameAndType (name = %s, type = %i)",
+ LLDB_SCOPED_TIMERF(
+ "Module::FindSymbolsWithNameAndType (name = %s, type = %i)",
name.AsCString(), symbol_type);
if (Symtab *symtab = GetSymtab()) {
std::vector<uint32_t> symbol_indexes;
@@ -1372,10 +1358,7 @@ void Module::FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
SymbolContextList &sc_list) {
// No need to protect this call using m_mutex all other method calls are
// already thread safe.
-
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat,
+ LLDB_SCOPED_TIMERF(
"Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",
regex.GetText().str().c_str(), symbol_type);
if (Symtab *symtab = GetSymtab()) {
diff --git a/contrib/llvm-project/lldb/source/Core/ModuleList.cpp b/contrib/llvm-project/lldb/source/Core/ModuleList.cpp
index 1701cb56338e..98f6ae2c62b0 100644
--- a/contrib/llvm-project/lldb/source/Core/ModuleList.cpp
+++ b/contrib/llvm-project/lldb/source/Core/ModuleList.cpp
@@ -82,8 +82,9 @@ ModuleListProperties::ModuleListProperties() {
[this] { UpdateSymlinkMappings(); });
llvm::SmallString<128> path;
- clang::driver::Driver::getDefaultModuleCachePath(path);
- SetClangModulesCachePath(path);
+ if (clang::driver::Driver::getDefaultModuleCachePath(path)) {
+ lldbassert(SetClangModulesCachePath(FileSpec(path)));
+ }
}
bool ModuleListProperties::GetEnableExternalLookup() const {
@@ -104,8 +105,8 @@ FileSpec ModuleListProperties::GetClangModulesCachePath() const {
->GetCurrentValue();
}
-bool ModuleListProperties::SetClangModulesCachePath(llvm::StringRef path) {
- return m_collection_sp->SetPropertyAtIndexAsString(
+bool ModuleListProperties::SetClangModulesCachePath(const FileSpec &path) {
+ return m_collection_sp->SetPropertyAtIndexAsFileSpec(
nullptr, ePropertyClangModulesCachePath, path);
}
@@ -296,14 +297,24 @@ size_t ModuleList::RemoveOrphans(bool mandatory) {
if (!lock.try_lock())
return 0;
}
- collection::iterator pos = m_modules.begin();
size_t remove_count = 0;
- while (pos != m_modules.end()) {
- if (pos->unique()) {
- pos = RemoveImpl(pos);
- ++remove_count;
- } else {
- ++pos;
+ // Modules might hold shared pointers to other modules, so removing one
+ // module might make other other modules orphans. Keep removing modules until
+ // there are no further modules that can be removed.
+ bool made_progress = true;
+ while (made_progress) {
+ // Keep track if we make progress this iteration.
+ made_progress = false;
+ collection::iterator pos = m_modules.begin();
+ while (pos != m_modules.end()) {
+ if (pos->unique()) {
+ pos = RemoveImpl(pos);
+ ++remove_count;
+ // We did make progress.
+ made_progress = true;
+ } else {
+ ++pos;
+ }
}
}
return remove_count;
@@ -335,10 +346,6 @@ void ModuleList::ClearImpl(bool use_notifier) {
Module *ModuleList::GetModulePointerAtIndex(size_t idx) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- return GetModulePointerAtIndexUnlocked(idx);
-}
-
-Module *ModuleList::GetModulePointerAtIndexUnlocked(size_t idx) const {
if (idx < m_modules.size())
return m_modules[idx].get();
return nullptr;
@@ -971,7 +978,7 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp,
error.SetErrorStringWithFormat(
"cannot locate a module for UUID '%s'", uuid_str.c_str());
else
- error.SetErrorStringWithFormat("cannot locate a module");
+ error.SetErrorString("cannot locate a module");
}
}
}
diff --git a/contrib/llvm-project/lldb/source/Core/PluginManager.cpp b/contrib/llvm-project/lldb/source/Core/PluginManager.cpp
index 3545ef66cc38..97e1e8d14039 100644
--- a/contrib/llvm-project/lldb/source/Core/PluginManager.cpp
+++ b/contrib/llvm-project/lldb/source/Core/PluginManager.cpp
@@ -264,12 +264,13 @@ public:
const std::vector<Instance> &GetInstances() const { return m_instances; }
std::vector<Instance> &GetInstances() { return m_instances; }
-private:
Instance *GetInstanceAtIndex(uint32_t idx) {
if (idx < m_instances.size())
return &m_instances[idx];
return nullptr;
}
+
+private:
std::vector<Instance> m_instances;
};
@@ -1005,6 +1006,67 @@ PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
return GetSymbolVendorInstances().GetCallbackAtIndex(idx);
}
+#pragma mark Trace
+
+struct TraceInstance : public PluginInstance<TraceCreateInstance> {
+ TraceInstance(ConstString name, std::string description,
+ CallbackType create_callback, llvm::StringRef schema,
+ TraceGetStartCommand get_start_command)
+ : PluginInstance<TraceCreateInstance>(name, std::move(description),
+ create_callback),
+ schema(schema), get_start_command(get_start_command) {}
+
+ llvm::StringRef schema;
+ TraceGetStartCommand get_start_command;
+};
+
+typedef PluginInstances<TraceInstance> TraceInstances;
+
+static TraceInstances &GetTracePluginInstances() {
+ static TraceInstances g_instances;
+ return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(ConstString name, const char *description,
+ TraceCreateInstance create_callback,
+ llvm::StringRef schema,
+ TraceGetStartCommand get_start_command) {
+ return GetTracePluginInstances().RegisterPlugin(
+ name, description, create_callback, schema, get_start_command);
+}
+
+bool PluginManager::UnregisterPlugin(TraceCreateInstance create_callback) {
+ return GetTracePluginInstances().UnregisterPlugin(create_callback);
+}
+
+TraceCreateInstance
+PluginManager::GetTraceCreateCallback(ConstString plugin_name) {
+ return GetTracePluginInstances().GetCallbackForName(plugin_name);
+}
+
+llvm::StringRef PluginManager::GetTraceSchema(ConstString plugin_name) {
+ for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
+ if (instance.name == plugin_name)
+ return instance.schema;
+ return llvm::StringRef();
+}
+
+CommandObjectSP
+PluginManager::GetTraceStartCommand(llvm::StringRef plugin_name,
+ CommandInterpreter &interpreter) {
+ for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
+ if (instance.name.GetStringRef() == plugin_name)
+ return instance.get_start_command(interpreter);
+ return CommandObjectSP();
+}
+
+llvm::StringRef PluginManager::GetTraceSchema(size_t index) {
+ if (TraceInstance *instance =
+ GetTracePluginInstances().GetInstanceAtIndex(index))
+ return instance->schema;
+ return llvm::StringRef();
+}
+
#pragma mark UnwindAssembly
typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance;
@@ -1218,6 +1280,7 @@ void PluginManager::DebuggerInitialize(Debugger &debugger) {
GetSymbolFileInstances().PerformDebuggerCallback(debugger);
GetOperatingSystemInstances().PerformDebuggerCallback(debugger);
GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger);
+ GetTracePluginInstances().PerformDebuggerCallback(debugger);
}
// This is the preferred new way to register plugin specific settings. e.g.
diff --git a/contrib/llvm-project/lldb/source/Core/SearchFilter.cpp b/contrib/llvm-project/lldb/source/Core/SearchFilter.cpp
index ea51fb379181..e3327ff5e750 100644
--- a/contrib/llvm-project/lldb/source/Core/SearchFilter.cpp
+++ b/contrib/llvm-project/lldb/source/Core/SearchFilter.cpp
@@ -89,7 +89,7 @@ SearchFilterSP SearchFilter::CreateFromStructuredData(
bool success = filter_dict.GetValueForKeyAsString(
GetSerializationSubclassKey(), subclass_name);
if (!success) {
- error.SetErrorStringWithFormat("Filter data missing subclass key");
+ error.SetErrorString("Filter data missing subclass key");
return result_sp;
}
@@ -228,11 +228,7 @@ void SearchFilter::SearchInModuleList(Searcher &searcher, ModuleList &modules) {
return;
}
- std::lock_guard<std::recursive_mutex> guard(modules.GetMutex());
- const size_t numModules = modules.GetSize();
-
- for (size_t i = 0; i < numModules; i++) {
- ModuleSP module_sp(modules.GetModuleAtIndexUnlocked(i));
+ for (ModuleSP module_sp : modules.Modules()) {
if (!ModulePasses(module_sp))
continue;
if (DoModuleIteration(module_sp, searcher) == Searcher::eCallbackReturnStop)
@@ -262,14 +258,9 @@ SearchFilter::DoModuleIteration(const SymbolContext &context,
return Searcher::eCallbackReturnContinue;
}
- const ModuleList &target_images = m_target_sp->GetImages();
- 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++) {
+ for (ModuleSP module_sp : m_target_sp->GetImages().Modules()) {
// If this is the last level supplied, then call the callback directly,
// otherwise descend.
- ModuleSP module_sp(target_images.GetModuleAtIndexUnlocked(i));
if (!ModulePasses(module_sp))
continue;
@@ -434,11 +425,9 @@ void SearchFilterByModule::Search(Searcher &searcher) {
const ModuleList &target_modules = m_target_sp->GetImages();
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++) {
- Module *module = target_modules.GetModulePointerAtIndexUnlocked(i);
- if (FileSpec::Match(m_module_spec, module->GetFileSpec())) {
- SymbolContext matchingContext(m_target_sp, module->shared_from_this());
+ for (ModuleSP module_sp : m_target_sp->GetImages().Modules()) {
+ if (FileSpec::Match(m_module_spec, module_sp->GetFileSpec())) {
+ SymbolContext matchingContext(m_target_sp, module_sp);
Searcher::CallbackReturn shouldContinue;
shouldContinue = DoModuleIteration(matchingContext, searcher);
@@ -550,17 +539,11 @@ void SearchFilterByModuleList::Search(Searcher &searcher) {
// If the module file spec is a full path, then we can just find the one
// filespec that passes. Otherwise, we need to go through all modules and
// find the ones that match the file name.
-
- const ModuleList &target_modules = m_target_sp->GetImages();
- 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++) {
- Module *module = target_modules.GetModulePointerAtIndexUnlocked(i);
- if (m_module_spec_list.FindFileIndex(0, module->GetFileSpec(), false) ==
+ for (ModuleSP module_sp : m_target_sp->GetImages().Modules()) {
+ if (m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) ==
UINT32_MAX)
continue;
- SymbolContext matchingContext(m_target_sp, module->shared_from_this());
+ SymbolContext matchingContext(m_target_sp, module_sp);
Searcher::CallbackReturn shouldContinue;
shouldContinue = DoModuleIteration(matchingContext, searcher);
@@ -752,13 +735,9 @@ void SearchFilterByModuleListAndCU::Search(Searcher &searcher) {
// find the ones that match the file name.
ModuleList matching_modules;
- const ModuleList &target_images = m_target_sp->GetImages();
- 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);
+ for (ModuleSP module_sp : m_target_sp->GetImages().Modules()) {
if (!no_modules_in_filter &&
m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) ==
UINT32_MAX)
diff --git a/contrib/llvm-project/lldb/source/Core/SourceManager.cpp b/contrib/llvm-project/lldb/source/Core/SourceManager.cpp
index 7414dd281d43..e79fcb48742d 100644
--- a/contrib/llvm-project/lldb/source/Core/SourceManager.cpp
+++ b/contrib/llvm-project/lldb/source/Core/SourceManager.cpp
@@ -183,14 +183,14 @@ size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile(
break;
}
- char prefix[32] = "";
+ std::string prefix;
if (bp_locs) {
uint32_t bp_count = bp_locs->NumLineEntriesWithLine(line);
if (bp_count > 0)
- ::snprintf(prefix, sizeof(prefix), "[%u] ", bp_count);
+ prefix = llvm::formatv("[{0}]", bp_count);
else
- ::snprintf(prefix, sizeof(prefix), " ");
+ prefix = " ";
}
char buffer[3];
@@ -206,7 +206,8 @@ size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile(
.str());
}
- s->Printf("%s%s %-4u\t", prefix, current_line_highlight.c_str(), line);
+ s->Printf("%s%s %-4u\t", prefix.c_str(), current_line_highlight.c_str(),
+ line);
// So far we treated column 0 as a special 'no column value', but
// DisplaySourceLines starts counting columns from 0 (and no column is
diff --git a/contrib/llvm-project/lldb/source/Core/Value.cpp b/contrib/llvm-project/lldb/source/Core/Value.cpp
index 63467644cdef..cc8f3f4e2615 100644
--- a/contrib/llvm-project/lldb/source/Core/Value.cpp
+++ b/contrib/llvm-project/lldb/source/Core/Value.cpp
@@ -39,27 +39,26 @@ using namespace lldb;
using namespace lldb_private;
Value::Value()
- : m_value(), m_vector(), m_compiler_type(), m_context(nullptr),
+ : m_value(), m_compiler_type(), m_context(nullptr),
m_value_type(eValueTypeScalar), m_context_type(eContextTypeInvalid),
m_data_buffer() {}
Value::Value(const Scalar &scalar)
- : m_value(scalar), m_vector(), m_compiler_type(), m_context(nullptr),
+ : m_value(scalar), m_compiler_type(), m_context(nullptr),
m_value_type(eValueTypeScalar), m_context_type(eContextTypeInvalid),
m_data_buffer() {}
Value::Value(const void *bytes, int len)
- : m_value(), m_vector(), m_compiler_type(), m_context(nullptr),
+ : m_value(), m_compiler_type(), m_context(nullptr),
m_value_type(eValueTypeHostAddress), m_context_type(eContextTypeInvalid),
m_data_buffer() {
SetBytes(bytes, len);
}
Value::Value(const Value &v)
- : m_value(v.m_value), m_vector(v.m_vector),
- m_compiler_type(v.m_compiler_type), m_context(v.m_context),
- m_value_type(v.m_value_type), m_context_type(v.m_context_type),
- m_data_buffer() {
+ : m_value(v.m_value), m_compiler_type(v.m_compiler_type),
+ m_context(v.m_context), m_value_type(v.m_value_type),
+ m_context_type(v.m_context_type), m_data_buffer() {
const uintptr_t rhs_value =
(uintptr_t)v.m_value.ULongLong(LLDB_INVALID_ADDRESS);
if ((rhs_value != 0) &&
@@ -74,7 +73,6 @@ Value::Value(const Value &v)
Value &Value::operator=(const Value &rhs) {
if (this != &rhs) {
m_value = rhs.m_value;
- m_vector = rhs.m_vector;
m_compiler_type = rhs.m_compiler_type;
m_context = rhs.m_context;
m_value_type = rhs.m_value_type;
@@ -115,7 +113,6 @@ Value::ValueType Value::GetValueType() const { return m_value_type; }
AddressType Value::GetValueAddressType() const {
switch (m_value_type) {
- default:
case eValueTypeScalar:
break;
case eValueTypeLoadAddress:
@@ -159,17 +156,6 @@ size_t Value::AppendDataToHostBuffer(const Value &rhs) {
}
}
} break;
- case eValueTypeVector: {
- const size_t vector_size = rhs.m_vector.length;
- if (vector_size > 0) {
- const size_t new_size = curr_size + vector_size;
- if (ResizeData(new_size) == new_size) {
- ::memcpy(m_data_buffer.GetBytes() + curr_size, rhs.m_vector.bytes,
- vector_size);
- return vector_size;
- }
- }
- } break;
case eValueTypeFileAddress:
case eValueTypeLoadAddress:
case eValueTypeHostAddress: {
@@ -291,9 +277,6 @@ lldb::Format Value::GetValueDefaultFormat() {
bool Value::GetData(DataExtractor &data) {
switch (m_value_type) {
- default:
- break;
-
case eValueTypeScalar:
if (m_value.GetData(data))
return true;
@@ -329,14 +312,6 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
return error;
switch (m_value_type) {
- case eValueTypeVector:
- if (ast_type.IsValid())
- data.SetAddressByteSize(ast_type.GetPointerByteSize());
- else
- data.SetAddressByteSize(sizeof(void *));
- data.SetData(m_vector.bytes, m_vector.length, m_vector.byte_order);
- break;
-
case eValueTypeScalar: {
data.SetByteOrder(endian::InlHostByteOrder());
if (ast_type.IsValid())
@@ -354,7 +329,7 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
return error; // Success;
}
- error.SetErrorStringWithFormat("extracting data from value failed");
+ error.SetErrorString("extracting data from value failed");
break;
}
case eValueTypeLoadAddress:
@@ -535,8 +510,7 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
if (address_type == eAddressTypeHost) {
// The address is an address in this process, so just copy it.
if (address == 0) {
- error.SetErrorStringWithFormat(
- "trying to read from host address of 0.");
+ error.SetErrorString("trying to read from host address of 0.");
return error;
}
memcpy(dst, reinterpret_cast<uint8_t *>(address), byte_size);
@@ -580,7 +554,7 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
address_type);
}
} else {
- error.SetErrorStringWithFormat("out of memory");
+ error.SetErrorString("out of memory");
}
return error;
@@ -593,7 +567,6 @@ Scalar &Value::ResolveValue(ExecutionContext *exe_ctx) {
case eValueTypeScalar: // raw scalar value
break;
- default:
case eValueTypeFileAddress:
case eValueTypeLoadAddress: // load address value
case eValueTypeHostAddress: // host address value (for memory in the process
@@ -604,8 +577,9 @@ Scalar &Value::ResolveValue(ExecutionContext *exe_ctx) {
Status error(GetValueAsData(exe_ctx, data, nullptr));
if (error.Success()) {
Scalar scalar;
- if (compiler_type.GetValueAsScalar(data, 0, data.GetByteSize(),
- scalar)) {
+ if (compiler_type.GetValueAsScalar(
+ data, 0, data.GetByteSize(), scalar,
+ exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr)) {
m_value = scalar;
m_value_type = eValueTypeScalar;
} else {
@@ -634,7 +608,6 @@ Variable *Value::GetVariable() {
void Value::Clear() {
m_value.Clear();
- m_vector.Clear();
m_compiler_type.Clear();
m_value_type = eValueTypeScalar;
m_context = nullptr;
@@ -646,8 +619,6 @@ const char *Value::GetValueTypeAsCString(ValueType value_type) {
switch (value_type) {
case eValueTypeScalar:
return "scalar";
- case eValueTypeVector:
- return "vector";
case eValueTypeFileAddress:
return "file address";
case eValueTypeLoadAddress:
diff --git a/contrib/llvm-project/lldb/source/Core/ValueObject.cpp b/contrib/llvm-project/lldb/source/Core/ValueObject.cpp
index 3a775b07e5e1..da90092336d6 100644
--- a/contrib/llvm-project/lldb/source/Core/ValueObject.cpp
+++ b/contrib/llvm-project/lldb/source/Core/ValueObject.cpp
@@ -337,7 +337,6 @@ const char *ValueObject::GetLocationAsCStringImpl(const Value &value,
switch (value_type) {
case Value::eValueTypeScalar:
- case Value::eValueTypeVector:
if (value.GetContextType() == Value::eContextTypeRegisterInfo) {
RegisterInfo *reg_info = value.GetRegisterInfo();
if (reg_info) {
@@ -352,8 +351,7 @@ const char *ValueObject::GetLocationAsCStringImpl(const Value &value,
}
}
if (m_location_str.empty())
- m_location_str =
- (value_type == Value::eValueTypeVector) ? "vector" : "scalar";
+ m_location_str = "scalar";
break;
case Value::eValueTypeLoadAddress:
@@ -849,7 +847,7 @@ bool ValueObject::SetData(DataExtractor &data, Status &error) {
uint64_t count = 0;
const Encoding encoding = GetCompilerType().GetEncoding(count);
- const size_t byte_size = GetByteSize();
+ const size_t byte_size = GetByteSize().getValueOr(0);
Value::ValueType value_type = m_value.GetValueType();
@@ -892,7 +890,6 @@ bool ValueObject::SetData(DataExtractor &data, Status &error) {
m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
} break;
case Value::eValueTypeFileAddress:
- case Value::eValueTypeVector:
break;
}
@@ -1459,7 +1456,6 @@ addr_t ValueObject::GetAddressOf(bool scalar_is_load_address,
switch (m_value.GetValueType()) {
case Value::eValueTypeScalar:
- case Value::eValueTypeVector:
if (scalar_is_load_address) {
if (address_type)
*address_type = eAddressTypeLoad;
@@ -1494,7 +1490,6 @@ addr_t ValueObject::GetPointerValue(AddressType *address_type) {
switch (m_value.GetValueType()) {
case Value::eValueTypeScalar:
- case Value::eValueTypeVector:
address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
break;
@@ -1524,7 +1519,7 @@ bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
uint64_t count = 0;
const Encoding encoding = GetCompilerType().GetEncoding(count);
- const size_t byte_size = GetByteSize();
+ const size_t byte_size = GetByteSize().getValueOr(0);
Value::ValueType value_type = m_value.GetValueType();
@@ -1577,7 +1572,6 @@ bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
} break;
case Value::eValueTypeFileAddress:
case Value::eValueTypeScalar:
- case Value::eValueTypeVector:
break;
}
} else {
@@ -1702,8 +1696,7 @@ ValueObjectSP ValueObject::GetSyntheticArrayMember(size_t index,
bool can_create) {
ValueObjectSP synthetic_child_sp;
if (IsPointerType() || IsArrayType()) {
- char index_str[64];
- snprintf(index_str, sizeof(index_str), "[%" PRIu64 "]", (uint64_t)index);
+ std::string index_str = llvm::formatv("[{0}]", index);
ConstString index_const_str(index_str);
// Check if we have already created a synthetic array member in this valid
// object. If we have we will re-use it.
@@ -1730,8 +1723,7 @@ ValueObjectSP ValueObject::GetSyntheticBitFieldChild(uint32_t from, uint32_t to,
bool can_create) {
ValueObjectSP synthetic_child_sp;
if (IsScalarType()) {
- char index_str[64];
- snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
+ std::string index_str = llvm::formatv("[{0}-{1}]", from, to);
ConstString index_const_str(index_str);
// Check if we have already created a synthetic array member in this valid
// object. If we have we will re-use it.
@@ -1741,13 +1733,13 @@ ValueObjectSP ValueObject::GetSyntheticBitFieldChild(uint32_t from, uint32_t to,
uint32_t bit_field_offset = from;
if (GetDataExtractor().GetByteOrder() == eByteOrderBig)
bit_field_offset =
- GetByteSize() * 8 - bit_field_size - bit_field_offset;
+ GetByteSize().getValueOr(0) * 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, GetCompilerType(), index_const_str, GetByteSize(), 0,
- bit_field_size, bit_field_offset, false, false, eAddressTypeInvalid,
- 0);
+ *this, GetCompilerType(), index_const_str,
+ GetByteSize().getValueOr(0), 0, bit_field_size, bit_field_offset,
+ false, false, eAddressTypeInvalid, 0);
// Cache the value if we got one back...
if (synthetic_child) {
@@ -1768,9 +1760,7 @@ ValueObjectSP ValueObject::GetSyntheticChildAtOffset(
ValueObjectSP synthetic_child_sp;
if (name_const_str.IsEmpty()) {
- char name_str[64];
- snprintf(name_str, sizeof(name_str), "@%i", offset);
- name_const_str.SetCString(name_str);
+ name_const_str.SetString("@" + std::to_string(offset));
}
// Check if we have already created a synthetic array member in this valid
@@ -3215,7 +3205,7 @@ bool ValueObject::CanProvideValue() {
// we need to support invalid types as providers of values because some bare-
// board debugging scenarios have no notion of types, but still manage to
// have raw numeric values for things like registers. sigh.
- const CompilerType &type(GetCompilerType());
+ CompilerType type = GetCompilerType();
return (!type.IsValid()) || (0 != (type.GetTypeInfo() & eTypeHasValue));
}
diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectCast.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectCast.cpp
index 22e856be539b..7b6d3591faf4 100644
--- a/contrib/llvm-project/lldb/source/Core/ValueObjectCast.cpp
+++ b/contrib/llvm-project/lldb/source/Core/ValueObjectCast.cpp
@@ -47,7 +47,7 @@ size_t ValueObjectCast::CalculateNumChildren(uint32_t max) {
return children_count <= max ? children_count : max;
}
-uint64_t ValueObjectCast::GetByteSize() {
+llvm::Optional<uint64_t> ValueObjectCast::GetByteSize() {
ExecutionContext exe_ctx(GetExecutionContextRef());
return m_value.GetValueByteSize(nullptr, &exe_ctx);
}
diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectChild.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectChild.cpp
index 6205ed32c615..34baa19f0a24 100644
--- a/contrib/llvm-project/lldb/source/Core/ValueObjectChild.cpp
+++ b/contrib/llvm-project/lldb/source/Core/ValueObjectChild.cpp
@@ -57,15 +57,8 @@ size_t ValueObjectChild::CalculateNumChildren(uint32_t max) {
static void AdjustForBitfieldness(ConstString &name,
uint8_t bitfield_bit_size) {
- if (name && bitfield_bit_size) {
- const char *compiler_type_name = name.AsCString();
- if (compiler_type_name) {
- std::vector<char> bitfield_type_name(strlen(compiler_type_name) + 32, 0);
- ::snprintf(&bitfield_type_name.front(), bitfield_type_name.size(),
- "%s:%u", compiler_type_name, bitfield_bit_size);
- name.SetCString(&bitfield_type_name.front());
- }
- }
+ if (name && bitfield_bit_size)
+ name.SetString(llvm::formatv("{0}:{1}", name, bitfield_bit_size).str());
}
ConstString ValueObjectChild::GetTypeName() {
@@ -118,8 +111,7 @@ bool ValueObjectChild::UpdateValue() {
CompilerType parent_type(parent->GetCompilerType());
// Copy the parent scalar value and the scalar value type
m_value.GetScalar() = parent->GetValue().GetScalar();
- Value::ValueType value_type = parent->GetValue().GetValueType();
- m_value.SetValueType(value_type);
+ m_value.SetValueType(parent->GetValue().GetValueType());
Flags parent_type_flags(parent_type.GetTypeInfo());
const bool is_instance_ptr_base =
@@ -127,97 +119,77 @@ bool ValueObjectChild::UpdateValue() {
(parent_type_flags.AnySet(lldb::eTypeInstanceIsPointer)));
if (parent->GetCompilerType().ShouldTreatScalarValueAsAddress()) {
- lldb::addr_t addr = parent->GetPointerValue();
- m_value.GetScalar() = addr;
-
+ m_value.GetScalar() = parent->GetPointerValue();
+
+ switch (parent->GetAddressTypeOfChildren()) {
+ case eAddressTypeFile: {
+ lldb::ProcessSP process_sp(GetProcessSP());
+ if (process_sp && process_sp->IsAlive())
+ m_value.SetValueType(Value::eValueTypeLoadAddress);
+ else
+ m_value.SetValueType(Value::eValueTypeFileAddress);
+ } break;
+ case eAddressTypeLoad:
+ m_value.SetValueType(is_instance_ptr_base
+ ? Value::eValueTypeScalar
+ : Value::eValueTypeLoadAddress);
+ break;
+ case eAddressTypeHost:
+ m_value.SetValueType(Value::eValueTypeHostAddress);
+ break;
+ case eAddressTypeInvalid:
+ // TODO: does this make sense?
+ m_value.SetValueType(Value::eValueTypeScalar);
+ break;
+ }
+ }
+ switch (m_value.GetValueType()) {
+ case Value::eValueTypeLoadAddress:
+ case Value::eValueTypeFileAddress:
+ case Value::eValueTypeHostAddress: {
+ lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
if (addr == LLDB_INVALID_ADDRESS) {
m_error.SetErrorString("parent address is invalid.");
} else if (addr == 0) {
m_error.SetErrorString("parent is NULL");
} else {
- m_value.GetScalar() += m_byte_offset;
- AddressType addr_type = parent->GetAddressTypeOfChildren();
-
- switch (addr_type) {
- case eAddressTypeFile: {
- lldb::ProcessSP process_sp(GetProcessSP());
- if (process_sp && process_sp->IsAlive())
- m_value.SetValueType(Value::eValueTypeLoadAddress);
- else
- m_value.SetValueType(Value::eValueTypeFileAddress);
- } break;
- case eAddressTypeLoad:
- m_value.SetValueType(is_instance_ptr_base
- ? Value::eValueTypeScalar
- : Value::eValueTypeLoadAddress);
- break;
- case eAddressTypeHost:
- m_value.SetValueType(Value::eValueTypeHostAddress);
- break;
- case eAddressTypeInvalid:
- // TODO: does this make sense?
- m_value.SetValueType(Value::eValueTypeScalar);
- break;
- }
- }
- } else {
- switch (value_type) {
- case Value::eValueTypeLoadAddress:
- case Value::eValueTypeFileAddress:
- case Value::eValueTypeHostAddress: {
- lldb::addr_t addr =
- m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
- if (addr == LLDB_INVALID_ADDRESS) {
- m_error.SetErrorString("parent address is invalid.");
- } else if (addr == 0) {
- m_error.SetErrorString("parent is NULL");
- } else {
- // Set this object's scalar value to the address of its value by
- // adding its byte offset to the parent address
- m_value.GetScalar() += GetByteOffset();
-
- // If a bitfield doesn't fit into the child_byte_size'd
- // window at child_byte_offset, move the window forward
- // until it fits. The problem here is that Value has no
- // notion of bitfields and thus the Value's DataExtractor
- // is sized like the bitfields CompilerType; a sequence of
- // bitfields, however, can be larger than their underlying
- // type.
- if (m_bitfield_bit_offset) {
- const bool thread_and_frame_only_if_stopped = true;
- ExecutionContext exe_ctx(GetExecutionContextRef().Lock(
- thread_and_frame_only_if_stopped));
- if (auto type_bit_size = GetCompilerType().GetBitSize(
- exe_ctx.GetBestExecutionContextScope())) {
- uint64_t bitfield_end =
- m_bitfield_bit_size + m_bitfield_bit_offset;
- if (bitfield_end > *type_bit_size) {
- uint64_t overhang_bytes =
- (bitfield_end - *type_bit_size + 7) / 8;
- m_value.GetScalar() += overhang_bytes;
- m_bitfield_bit_offset -= overhang_bytes * 8;
- }
+ // If a bitfield doesn't fit into the child_byte_size'd window at
+ // child_byte_offset, move the window forward until it fits. The
+ // problem here is that Value has no notion of bitfields and thus the
+ // Value's DataExtractor is sized like the bitfields CompilerType; a
+ // sequence of bitfields, however, can be larger than their underlying
+ // type.
+ if (m_bitfield_bit_offset) {
+ const bool thread_and_frame_only_if_stopped = true;
+ ExecutionContext exe_ctx(GetExecutionContextRef().Lock(
+ thread_and_frame_only_if_stopped));
+ if (auto type_bit_size = GetCompilerType().GetBitSize(
+ exe_ctx.GetBestExecutionContextScope())) {
+ uint64_t bitfield_end =
+ m_bitfield_bit_size + m_bitfield_bit_offset;
+ if (bitfield_end > *type_bit_size) {
+ uint64_t overhang_bytes =
+ (bitfield_end - *type_bit_size + 7) / 8;
+ m_byte_offset += overhang_bytes;
+ m_bitfield_bit_offset -= overhang_bytes * 8;
}
}
}
- } break;
- case Value::eValueTypeScalar:
- // try to extract the child value from the parent's scalar value
- {
- Scalar scalar(m_value.GetScalar());
- if (m_bitfield_bit_size)
- scalar.ExtractBitfield(m_bitfield_bit_size,
- m_bitfield_bit_offset);
- else
- scalar.ExtractBitfield(8 * m_byte_size, 8 * m_byte_offset);
- m_value.GetScalar() = scalar;
- }
- break;
- default:
- m_error.SetErrorString("parent has invalid value.");
- break;
+ // Set this object's scalar value to the address of its value by
+ // adding its byte offset to the parent address
+ m_value.GetScalar() += m_byte_offset;
+ }
+ } break;
+
+ case Value::eValueTypeScalar:
+ // try to extract the child value from the parent's scalar value
+ {
+ Scalar scalar(m_value.GetScalar());
+ scalar.ExtractBitfield(8 * m_byte_size, 8 * m_byte_offset);
+ m_value.GetScalar() = scalar;
}
+ break;
}
if (m_error.Success()) {
diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResult.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResult.cpp
index 8d84f8e62ccc..ceb4491f8666 100644
--- a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResult.cpp
+++ b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResult.cpp
@@ -40,8 +40,7 @@ ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,
ByteOrder byte_order,
uint32_t addr_byte_size,
lldb::addr_t address)
- : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0),
- m_impl(this, address) {
+ : ValueObject(exe_scope, manager), m_impl(this, address) {
SetIsConstant();
SetValueIsValid(true);
m_data.SetByteOrder(byte_order);
@@ -64,8 +63,7 @@ ValueObjectConstResult::ValueObjectConstResult(
ExecutionContextScope *exe_scope, ValueObjectManager &manager,
const CompilerType &compiler_type, ConstString name,
const DataExtractor &data, lldb::addr_t address)
- : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0),
- m_impl(this, address) {
+ : ValueObject(exe_scope, manager), m_impl(this, address) {
m_data = data;
if (!m_data.GetSharedDataBuffer()) {
@@ -112,8 +110,7 @@ ValueObjectConstResult::ValueObjectConstResult(
const CompilerType &compiler_type, ConstString name,
const lldb::DataBufferSP &data_sp, lldb::ByteOrder data_byte_order,
uint32_t data_addr_size, lldb::addr_t address)
- : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0),
- m_impl(this, address) {
+ : ValueObject(exe_scope, manager), m_impl(this, address) {
m_data.SetByteOrder(data_byte_order);
m_data.SetAddressByteSize(data_addr_size);
m_data.SetData(data_sp);
@@ -143,7 +140,7 @@ ValueObjectConstResult::ValueObjectConstResult(
ExecutionContextScope *exe_scope, ValueObjectManager &manager,
const CompilerType &compiler_type, ConstString name, lldb::addr_t address,
AddressType address_type, uint32_t addr_byte_size)
- : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0),
+ : ValueObject(exe_scope, manager), m_type_name(),
m_impl(this, address) {
m_value.GetScalar() = address;
m_data.SetAddressByteSize(addr_byte_size);
@@ -179,8 +176,7 @@ ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,
ValueObjectManager &manager,
const Status &error)
- : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0),
- m_impl(this) {
+ : ValueObject(exe_scope, manager), m_impl(this) {
m_error = error;
SetIsConstant();
}
@@ -189,8 +185,7 @@ ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,
ValueObjectManager &manager,
const Value &value,
ConstString name, Module *module)
- : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0),
- m_impl(this) {
+ : ValueObject(exe_scope, manager), m_impl(this) {
m_value = value;
m_name = name;
ExecutionContext exe_ctx;
@@ -208,9 +203,9 @@ lldb::ValueType ValueObjectConstResult::GetValueType() const {
return eValueTypeConstResult;
}
-uint64_t ValueObjectConstResult::GetByteSize() {
+llvm::Optional<uint64_t> ValueObjectConstResult::GetByteSize() {
ExecutionContext exe_ctx(GetExecutionContextRef());
- if (m_byte_size == 0) {
+ if (!m_byte_size) {
if (auto size =
GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope()))
SetByteSize(*size);
diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp
index ca66740cb55d..1c25b8c85a05 100644
--- a/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp
+++ b/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp
@@ -98,7 +98,7 @@ size_t ValueObjectDynamicValue::CalculateNumChildren(uint32_t max) {
return m_parent->GetNumChildren(max);
}
-uint64_t ValueObjectDynamicValue::GetByteSize() {
+llvm::Optional<uint64_t> ValueObjectDynamicValue::GetByteSize() {
const bool success = UpdateValueIfNeeded(false);
if (success && m_dynamic_type_info.HasType()) {
ExecutionContext exe_ctx(GetExecutionContextRef());
diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectMemory.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectMemory.cpp
index 91b2c6084928..abf7b38ed89a 100644
--- a/contrib/llvm-project/lldb/source/Core/ValueObjectMemory.cpp
+++ b/contrib/llvm-project/lldb/source/Core/ValueObjectMemory.cpp
@@ -139,10 +139,11 @@ size_t ValueObjectMemory::CalculateNumChildren(uint32_t max) {
return child_count <= max ? child_count : max;
}
-uint64_t ValueObjectMemory::GetByteSize() {
+llvm::Optional<uint64_t> ValueObjectMemory::GetByteSize() {
+ ExecutionContext exe_ctx(GetExecutionContextRef());
if (m_type_sp)
- return m_type_sp->GetByteSize().getValueOr(0);
- return m_compiler_type.GetByteSize(nullptr).getValueOr(0);
+ return m_type_sp->GetByteSize(exe_ctx.GetBestExecutionContextScope());
+ return m_compiler_type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
}
lldb::ValueType ValueObjectMemory::GetValueType() const {
@@ -167,9 +168,6 @@ bool ValueObjectMemory::UpdateValue() {
Value::ValueType value_type = m_value.GetValueType();
switch (value_type) {
- default:
- llvm_unreachable("Unhandled expression result value kind...");
-
case Value::eValueTypeScalar:
// The variable value is in the Scalar value inside the m_value. We can
// point our m_data right to it.
diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp
index ec87c38fb367..27461e9cebc4 100644
--- a/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp
+++ b/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp
@@ -81,7 +81,7 @@ size_t ValueObjectRegisterSet::CalculateNumChildren(uint32_t max) {
return 0;
}
-uint64_t ValueObjectRegisterSet::GetByteSize() { return 0; }
+llvm::Optional<uint64_t> ValueObjectRegisterSet::GetByteSize() { return 0; }
bool ValueObjectRegisterSet::UpdateValue() {
m_error.Clear();
@@ -229,7 +229,9 @@ size_t ValueObjectRegister::CalculateNumChildren(uint32_t max) {
return children_count <= max ? children_count : max;
}
-uint64_t ValueObjectRegister::GetByteSize() { return m_reg_info.byte_size; }
+llvm::Optional<uint64_t> ValueObjectRegister::GetByteSize() {
+ return m_reg_info.byte_size;
+}
bool ValueObjectRegister::UpdateValue() {
m_error.Clear();
diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp
index 32d1e6ab8368..cebf7abfe523 100644
--- a/contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp
+++ b/contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp
@@ -46,7 +46,7 @@ public:
ValueObjectSynthetic::ValueObjectSynthetic(ValueObject &parent,
lldb::SyntheticChildrenSP filter)
- : ValueObject(parent), m_synth_sp(filter), m_children_byindex(),
+ : ValueObject(parent), m_synth_sp(std::move(filter)), m_children_byindex(),
m_name_toindex(), m_synthetic_children_cache(),
m_synthetic_children_count(UINT32_MAX),
m_parent_type_name(parent.GetTypeName()),
@@ -121,7 +121,9 @@ bool ValueObjectSynthetic::MightHaveChildren() {
return (m_might_have_children != eLazyBoolNo);
}
-uint64_t ValueObjectSynthetic::GetByteSize() { return m_parent->GetByteSize(); }
+llvm::Optional<uint64_t> ValueObjectSynthetic::GetByteSize() {
+ return m_parent->GetByteSize();
+}
lldb::ValueType ValueObjectSynthetic::GetValueType() const {
return m_parent->GetValueType();
diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectVariable.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectVariable.cpp
index 0d1e7b047a0a..5acb23aaac5b 100644
--- a/contrib/llvm-project/lldb/source/Core/ValueObjectVariable.cpp
+++ b/contrib/llvm-project/lldb/source/Core/ValueObjectVariable.cpp
@@ -105,15 +105,15 @@ size_t ValueObjectVariable::CalculateNumChildren(uint32_t max) {
return child_count <= max ? child_count : max;
}
-uint64_t ValueObjectVariable::GetByteSize() {
+llvm::Optional<uint64_t> ValueObjectVariable::GetByteSize() {
ExecutionContext exe_ctx(GetExecutionContextRef());
CompilerType type(GetCompilerType());
if (!type.IsValid())
- return 0;
+ return {};
- return type.GetByteSize(exe_ctx.GetBestExecutionContextScope()).getValueOr(0);
+ return type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
}
lldb::ValueType ValueObjectVariable::GetValueType() const {
@@ -132,8 +132,11 @@ bool ValueObjectVariable::UpdateValue() {
if (variable->GetLocationIsConstantValueData()) {
// expr doesn't contain DWARF bytes, it contains the constant variable
// value bytes themselves...
- if (expr.GetExpressionData(m_data))
+ if (expr.GetExpressionData(m_data)) {
+ if (m_data.GetDataStart() && m_data.GetByteSize())
+ m_value.SetBytes(m_data.GetDataStart(), m_data.GetByteSize());
m_value.SetContext(Value::eContextTypeVariable, variable);
+ }
else
m_error.SetErrorString("empty constant data");
// constant bytes can't be edited - sorry
@@ -193,8 +196,6 @@ bool ValueObjectVariable::UpdateValue() {
const bool process_is_alive = process && process->IsAlive();
switch (value_type) {
- case Value::eValueTypeVector:
- // fall through
case Value::eValueTypeScalar:
// The variable value is in the Scalar value inside the m_value. We can
// point our m_data right to it.
@@ -292,7 +293,6 @@ void ValueObjectVariable::DoUpdateChildrenAddressType(ValueObject &valobj) {
break;
case Value::eValueTypeLoadAddress:
case Value::eValueTypeScalar:
- case Value::eValueTypeVector:
valobj.SetAddressTypeOfChildren(eAddressTypeLoad);
break;
}
diff --git a/contrib/llvm-project/lldb/source/DataFormatters/DataVisualization.cpp b/contrib/llvm-project/lldb/source/DataFormatters/DataVisualization.cpp
index 450a5cbc3ef3..ded8bbd90391 100644
--- a/contrib/llvm-project/lldb/source/DataFormatters/DataVisualization.cpp
+++ b/contrib/llvm-project/lldb/source/DataFormatters/DataVisualization.cpp
@@ -169,13 +169,12 @@ DataVisualization::Categories::GetCategoryAtIndex(size_t index) {
bool DataVisualization::NamedSummaryFormats::GetSummaryFormat(
ConstString type, lldb::TypeSummaryImplSP &entry) {
- return GetFormatManager().GetNamedSummaryContainer().Get(type, entry);
+ return GetFormatManager().GetNamedSummaryContainer().GetExact(type, entry);
}
void DataVisualization::NamedSummaryFormats::Add(
ConstString type, const lldb::TypeSummaryImplSP &entry) {
- GetFormatManager().GetNamedSummaryContainer().Add(
- FormatManager::GetValidTypeName(type), entry);
+ GetFormatManager().GetNamedSummaryContainer().Add(type, entry);
}
bool DataVisualization::NamedSummaryFormats::Delete(ConstString type) {
@@ -187,7 +186,7 @@ void DataVisualization::NamedSummaryFormats::Clear() {
}
void DataVisualization::NamedSummaryFormats::ForEach(
- std::function<bool(ConstString, const lldb::TypeSummaryImplSP &)>
+ std::function<bool(const TypeMatcher &, const lldb::TypeSummaryImplSP &)>
callback) {
GetFormatManager().GetNamedSummaryContainer().ForEach(callback);
}
diff --git a/contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp b/contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp
index ad02d37360b8..6c824d1f7728 100644
--- a/contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp
+++ b/contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp
@@ -237,7 +237,9 @@ void FormatManager::GetPossibleMatches(
// stripped.
uint64_t array_size;
if (compiler_type.IsArrayType(nullptr, &array_size, nullptr)) {
- CompilerType element_type = compiler_type.GetArrayElementType();
+ ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
+ CompilerType element_type = compiler_type.GetArrayElementType(
+ exe_ctx.GetBestExecutionContextScope());
if (element_type.IsTypedefType()) {
// Get the stripped element type and compute the stripped array type
// from it.
@@ -551,10 +553,6 @@ bool FormatManager::ShouldPrintAsOneLiner(ValueObject &valobj) {
return true;
}
-ConstString FormatManager::GetValidTypeName(ConstString type) {
- return ::GetValidTypeName_Impl(type);
-}
-
ConstString FormatManager::GetTypeForCache(ValueObject &valobj,
lldb::DynamicValueType use_dynamic) {
ValueObjectSP valobj_sp = valobj.GetQualifiedRepresentationIfAvailable(
diff --git a/contrib/llvm-project/lldb/source/DataFormatters/TypeCategory.cpp b/contrib/llvm-project/lldb/source/DataFormatters/TypeCategory.cpp
index 8368c91a57f1..f1c6210edd1a 100644
--- a/contrib/llvm-project/lldb/source/DataFormatters/TypeCategory.cpp
+++ b/contrib/llvm-project/lldb/source/DataFormatters/TypeCategory.cpp
@@ -15,11 +15,9 @@ using namespace lldb_private;
TypeCategoryImpl::TypeCategoryImpl(IFormatChangeListener *clist,
ConstString name)
- : m_format_cont("format", "regex-format", clist),
- m_summary_cont("summary", "regex-summary", clist),
- m_filter_cont("filter", "regex-filter", clist),
- m_synth_cont("synth", "regex-synth", clist), m_enabled(false),
- m_change_listener(clist), m_mutex(), m_name(name), m_languages() {}
+ : m_format_cont(clist), m_summary_cont(clist), m_filter_cont(clist),
+ m_synth_cont(clist), m_enabled(false), m_change_listener(clist),
+ m_mutex(), m_name(name), m_languages() {}
static bool IsApplicable(lldb::LanguageType category_lang,
lldb::LanguageType valobj_lang) {
diff --git a/contrib/llvm-project/lldb/source/DataFormatters/ValueObjectPrinter.cpp b/contrib/llvm-project/lldb/source/DataFormatters/ValueObjectPrinter.cpp
index c8a306334cf5..082ad344d2d1 100644
--- a/contrib/llvm-project/lldb/source/DataFormatters/ValueObjectPrinter.cpp
+++ b/contrib/llvm-project/lldb/source/DataFormatters/ValueObjectPrinter.cpp
@@ -355,22 +355,33 @@ void ValueObjectPrinter::GetValueSummaryError(std::string &value,
if (err_cstr)
error.assign(err_cstr);
- if (ShouldPrintValueObject()) {
- if (IsNil())
- summary.assign("nil");
- else if (IsUninitialized())
- summary.assign("<uninitialized>");
- else if (m_options.m_omit_summary_depth == 0) {
- TypeSummaryImpl *entry = GetSummaryFormatter();
- if (entry)
- m_valobj->GetSummaryAsCString(entry, summary,
- m_options.m_varformat_language);
- else {
- const char *sum_cstr =
- m_valobj->GetSummaryAsCString(m_options.m_varformat_language);
- if (sum_cstr)
- summary.assign(sum_cstr);
- }
+ if (!ShouldPrintValueObject())
+ return;
+
+ if (IsNil()) {
+ lldb::LanguageType lang_type =
+ (m_options.m_varformat_language == lldb::eLanguageTypeUnknown)
+ ? m_valobj->GetPreferredDisplayLanguage()
+ : m_options.m_varformat_language;
+ if (Language *lang_plugin = Language::FindPlugin(lang_type)) {
+ summary.assign(lang_plugin->GetNilReferenceSummaryString().str());
+ } else {
+ // We treat C as the fallback language rather than as a separate Language
+ // plugin.
+ summary.assign("NULL");
+ }
+ } else if (IsUninitialized()) {
+ summary.assign("<uninitialized>");
+ } else if (m_options.m_omit_summary_depth == 0) {
+ TypeSummaryImpl *entry = GetSummaryFormatter();
+ if (entry) {
+ m_valobj->GetSummaryAsCString(entry, summary,
+ m_options.m_varformat_language);
+ } else {
+ const char *sum_cstr =
+ m_valobj->GetSummaryAsCString(m_options.m_varformat_language);
+ if (sum_cstr)
+ summary.assign(sum_cstr);
}
}
}
@@ -403,7 +414,9 @@ bool ValueObjectPrinter::PrintValueAndSummaryIfNeeded(bool &value_printed,
// this thing is nil (but show the value if the user passes a format
// explicitly)
TypeSummaryImpl *entry = GetSummaryFormatter();
- if (!IsNil() && !IsUninitialized() && !m_value.empty() &&
+ const bool has_nil_or_uninitialized_summary =
+ (IsNil() || IsUninitialized()) && !m_summary.empty();
+ if (!has_nil_or_uninitialized_summary && !m_value.empty() &&
(entry == nullptr ||
(entry->DoesPrintValue(m_valobj) ||
m_options.m_format != eFormatDefault) ||
diff --git a/contrib/llvm-project/lldb/source/DataFormatters/VectorType.cpp b/contrib/llvm-project/lldb/source/DataFormatters/VectorType.cpp
index fd1c0bc96cd4..cc24bb1de428 100644
--- a/contrib/llvm-project/lldb/source/DataFormatters/VectorType.cpp
+++ b/contrib/llvm-project/lldb/source/DataFormatters/VectorType.cpp
@@ -220,20 +220,8 @@ public:
CompilerType parent_type(m_backend.GetCompilerType());
CompilerType element_type;
parent_type.IsVectorType(&element_type, nullptr);
- TypeSystem *type_system = nullptr;
- if (auto target_sp = m_backend.GetTargetSP()) {
- auto type_system_or_err =
- target_sp->GetScratchTypeSystemForLanguage(lldb::eLanguageTypeC);
- if (auto err = type_system_or_err.takeError()) {
- LLDB_LOG_ERROR(
- lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS),
- std::move(err), "Unable to update from scratch TypeSystem");
- } else {
- type_system = &type_system_or_err.get();
- }
- }
- m_child_type =
- ::GetCompilerTypeForFormat(m_parent_format, element_type, type_system);
+ m_child_type = ::GetCompilerTypeForFormat(m_parent_format, element_type,
+ parent_type.GetTypeSystem());
m_num_children = ::CalculateNumChildren(parent_type, m_child_type);
m_item_format = GetItemFormatForFormat(m_parent_format, m_child_type);
return false;
diff --git a/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp b/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp
index 6050c1922564..c30fdf565cd5 100644
--- a/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp
+++ b/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp
@@ -89,8 +89,8 @@ void DWARFExpression::DumpLocation(Stream *s, const DataExtractor &data,
lldb::DescriptionLevel level,
ABI *abi) const {
llvm::DWARFExpression(data.GetAsLLVM(), data.GetAddressByteSize())
- .print(s->AsRawOstream(), abi ? &abi->GetMCRegisterInfo() : nullptr,
- nullptr);
+ .print(s->AsRawOstream(), llvm::DIDumpOptions(),
+ abi ? &abi->GetMCRegisterInfo() : nullptr, nullptr);
}
void DWARFExpression::SetLocationListAddresses(addr_t cu_file_addr,
@@ -158,7 +158,7 @@ static bool ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
Value &value) {
if (reg_ctx == nullptr) {
if (error_ptr)
- error_ptr->SetErrorStringWithFormat("No register context in frame.\n");
+ error_ptr->SetErrorString("No register context in frame.\n");
} else {
uint32_t native_reg =
reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
@@ -941,6 +941,16 @@ bool DWARFExpression::Evaluate(
Value pieces; // Used for DW_OP_piece
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ // A generic type is "an integral type that has the size of an address and an
+ // unspecified signedness". For now, just use the signedness of the operand.
+ // TODO: Implement a real typed stack, and store the genericness of the value
+ // there.
+ auto to_generic = [&](auto v) {
+ bool is_signed = std::is_signed<decltype(v)>::value;
+ return Scalar(llvm::APSInt(
+ llvm::APInt(8 * opcodes.GetAddressByteSize(), v, is_signed),
+ !is_signed));
+ };
while (opcodes.ValidOffset(offset)) {
const lldb::offset_t op_offset = offset;
@@ -1036,22 +1046,21 @@ bool DWARFExpression::Evaluate(
LLDB_INVALID_ADDRESS);
if (!module_sp) {
if (error_ptr)
- error_ptr->SetErrorStringWithFormat(
+ error_ptr->SetErrorString(
"need module to resolve file address for DW_OP_deref");
return false;
}
Address so_addr;
if (!module_sp->ResolveFileAddress(file_addr, so_addr)) {
if (error_ptr)
- error_ptr->SetErrorStringWithFormat(
+ error_ptr->SetErrorString(
"failed to resolve file address in module");
return false;
}
addr_t load_Addr = so_addr.GetLoadAddress(exe_ctx->GetTargetPtr());
if (load_Addr == LLDB_INVALID_ADDRESS) {
if (error_ptr)
- error_ptr->SetErrorStringWithFormat(
- "failed to resolve load address");
+ error_ptr->SetErrorString("failed to resolve load address");
return false;
}
stack.back().GetScalar() = load_Addr;
@@ -1079,13 +1088,12 @@ bool DWARFExpression::Evaluate(
}
} else {
if (error_ptr)
- error_ptr->SetErrorStringWithFormat(
- "NULL process for DW_OP_deref.\n");
+ error_ptr->SetErrorString("NULL process for DW_OP_deref.\n");
return false;
}
} else {
if (error_ptr)
- error_ptr->SetErrorStringWithFormat(
+ error_ptr->SetErrorString(
"NULL execution context for DW_OP_deref.\n");
return false;
}
@@ -1199,13 +1207,12 @@ bool DWARFExpression::Evaluate(
}
} else {
if (error_ptr)
- error_ptr->SetErrorStringWithFormat(
- "NULL process for DW_OP_deref.\n");
+ error_ptr->SetErrorString("NULL process for DW_OP_deref.\n");
return false;
}
} else {
if (error_ptr)
- error_ptr->SetErrorStringWithFormat(
+ error_ptr->SetErrorString(
"NULL execution context for DW_OP_deref.\n");
return false;
}
@@ -1254,37 +1261,42 @@ bool DWARFExpression::Evaluate(
// All DW_OP_constXXX opcodes have a single operand as noted below:
//
// Opcode Operand 1
- // DW_OP_const1u 1-byte unsigned integer constant DW_OP_const1s
- // 1-byte signed integer constant DW_OP_const2u 2-byte unsigned integer
- // constant DW_OP_const2s 2-byte signed integer constant DW_OP_const4u
- // 4-byte unsigned integer constant DW_OP_const4s 4-byte signed integer
- // constant DW_OP_const8u 8-byte unsigned integer constant DW_OP_const8s
- // 8-byte signed integer constant DW_OP_constu unsigned LEB128 integer
- // constant DW_OP_consts signed LEB128 integer constant
+ // DW_OP_const1u 1-byte unsigned integer constant
+ // DW_OP_const1s 1-byte signed integer constant
+ // DW_OP_const2u 2-byte unsigned integer constant
+ // DW_OP_const2s 2-byte signed integer constant
+ // DW_OP_const4u 4-byte unsigned integer constant
+ // DW_OP_const4s 4-byte signed integer constant
+ // DW_OP_const8u 8-byte unsigned integer constant
+ // DW_OP_const8s 8-byte signed integer constant
+ // DW_OP_constu unsigned LEB128 integer constant
+ // DW_OP_consts signed LEB128 integer constant
case DW_OP_const1u:
- stack.push_back(Scalar((uint8_t)opcodes.GetU8(&offset)));
+ stack.push_back(to_generic(opcodes.GetU8(&offset)));
break;
case DW_OP_const1s:
- stack.push_back(Scalar((int8_t)opcodes.GetU8(&offset)));
+ stack.push_back(to_generic((int8_t)opcodes.GetU8(&offset)));
break;
case DW_OP_const2u:
- stack.push_back(Scalar((uint16_t)opcodes.GetU16(&offset)));
+ stack.push_back(to_generic(opcodes.GetU16(&offset)));
break;
case DW_OP_const2s:
- stack.push_back(Scalar((int16_t)opcodes.GetU16(&offset)));
+ stack.push_back(to_generic((int16_t)opcodes.GetU16(&offset)));
break;
case DW_OP_const4u:
- stack.push_back(Scalar((uint32_t)opcodes.GetU32(&offset)));
+ stack.push_back(to_generic(opcodes.GetU32(&offset)));
break;
case DW_OP_const4s:
- stack.push_back(Scalar((int32_t)opcodes.GetU32(&offset)));
+ stack.push_back(to_generic((int32_t)opcodes.GetU32(&offset)));
break;
case DW_OP_const8u:
- stack.push_back(Scalar((uint64_t)opcodes.GetU64(&offset)));
+ stack.push_back(to_generic(opcodes.GetU64(&offset)));
break;
case DW_OP_const8s:
- stack.push_back(Scalar((int64_t)opcodes.GetU64(&offset)));
+ stack.push_back(to_generic((int64_t)opcodes.GetU64(&offset)));
break;
+ // These should also use to_generic, but we can't do that due to a
+ // producer-side bug in llvm. See llvm.org/pr48087.
case DW_OP_constu:
stack.push_back(Scalar(opcodes.GetULEB128(&offset)));
break;
@@ -1891,7 +1903,7 @@ bool DWARFExpression::Evaluate(
case DW_OP_lit29:
case DW_OP_lit30:
case DW_OP_lit31:
- stack.push_back(Scalar((uint64_t)(op - DW_OP_lit0)));
+ stack.push_back(to_generic(op - DW_OP_lit0));
break;
// OPCODE: DW_OP_regN
@@ -2036,7 +2048,7 @@ bool DWARFExpression::Evaluate(
}
} else {
if (error_ptr)
- error_ptr->SetErrorStringWithFormat(
+ error_ptr->SetErrorString(
"NULL execution context for DW_OP_fbreg.\n");
return false;
}
@@ -2156,20 +2168,6 @@ bool DWARFExpression::Evaluate(
ap_int.getNumWords()};
curr_piece.GetScalar() = Scalar(llvm::APInt(bit_size, buf));
} break;
-
- case Value::eValueTypeVector: {
- if (curr_piece_source_value.GetVector().length >= piece_byte_size)
- curr_piece_source_value.GetVector().length = piece_byte_size;
- else {
- if (error_ptr)
- error_ptr->SetErrorStringWithFormat(
- "unable to extract %" PRIu64 " bytes from a %" PRIu64
- " byte vector value.",
- piece_byte_size,
- (uint64_t)curr_piece_source_value.GetVector().length);
- return false;
- }
- } break;
}
// Check if this is the first piece?
@@ -2238,19 +2236,33 @@ bool DWARFExpression::Evaluate(
piece_bit_size, piece_bit_offset);
}
return false;
-
- case Value::eValueTypeVector:
- if (error_ptr) {
- error_ptr->SetErrorStringWithFormat(
- "unable to extract DW_OP_bit_piece(bit_size = %" PRIu64
- ", bit_offset = %" PRIu64 ") from a vector value.",
- piece_bit_size, piece_bit_offset);
- }
- return false;
}
}
break;
+ // OPCODE: DW_OP_implicit_value
+ // OPERANDS: 2
+ // ULEB128 size of the value block in bytes
+ // uint8_t* block bytes encoding value in target's memory
+ // representation
+ // DESCRIPTION: Value is immediately stored in block in the debug info with
+ // the memory representation of the target.
+ case DW_OP_implicit_value: {
+ const uint32_t len = opcodes.GetULEB128(&offset);
+ const void *data = opcodes.GetData(&offset, len);
+
+ if (!data) {
+ LLDB_LOG(log, "Evaluate_DW_OP_implicit_value: could not be read data");
+ LLDB_ERRORF(error_ptr, "Could not evaluate %s.",
+ DW_OP_value_to_name(op));
+ return false;
+ }
+
+ Value result(data, len);
+ stack.push_back(result);
+ break;
+ }
+
// OPCODE: DW_OP_push_object_address
// OPERANDS: none
// DESCRIPTION: Pushes the address of the object currently being
diff --git a/contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp b/contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp
index d95f0745cf4b..8b3dda7b2fe1 100644
--- a/contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp
+++ b/contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp
@@ -16,10 +16,10 @@ using namespace lldb_private;
ExpressionVariable::~ExpressionVariable() {}
uint8_t *ExpressionVariable::GetValueBytes() {
- const size_t byte_size = m_frozen_sp->GetByteSize();
- if (byte_size > 0) {
- if (m_frozen_sp->GetDataExtractor().GetByteSize() < byte_size) {
- m_frozen_sp->GetValue().ResizeData(byte_size);
+ llvm::Optional<uint64_t> byte_size = m_frozen_sp->GetByteSize();
+ if (byte_size && *byte_size) {
+ if (m_frozen_sp->GetDataExtractor().GetByteSize() < *byte_size) {
+ m_frozen_sp->GetValue().ResizeData(*byte_size);
m_frozen_sp->GetValue().GetData(m_frozen_sp->GetDataExtractor());
}
return const_cast<uint8_t *>(
diff --git a/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp b/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp
index e3c9c1d7fdf5..538935da52ee 100644
--- a/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp
+++ b/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp
@@ -328,8 +328,7 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
if (function.isDeclaration() || function.hasPrivateLinkage())
continue;
- const bool external =
- function.hasExternalLinkage() || function.hasLinkOnceODRLinkage();
+ const bool external = !function.hasLocalLinkage();
void *fun_ptr = m_execution_engine_up->getPointerToFunction(&function);
diff --git a/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp b/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp
index 4c7a65626598..b87a759aadc5 100644
--- a/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp
+++ b/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp
@@ -1356,14 +1356,14 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
// Check we can actually get a thread
if (exe_ctx.GetThreadPtr() == nullptr) {
error.SetErrorToGenericError();
- error.SetErrorStringWithFormat("unable to acquire thread");
+ error.SetErrorString("unable to acquire thread");
return false;
}
// Make sure we have a valid process
if (!exe_ctx.GetProcessPtr()) {
error.SetErrorToGenericError();
- error.SetErrorStringWithFormat("unable to get the process");
+ error.SetErrorString("unable to get the process");
return false;
}
@@ -1404,7 +1404,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
static lldb_private::ABI::CallArgument rawArgs[16];
if (numArgs >= 16) {
error.SetErrorToGenericError();
- error.SetErrorStringWithFormat("function takes too many arguments");
+ error.SetErrorString("function takes too many arguments");
return false;
}
@@ -1490,7 +1490,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
// Check that the thread plan completed successfully
if (res != lldb::ExpressionResults::eExpressionCompleted) {
error.SetErrorToGenericError();
- error.SetErrorStringWithFormat("ThreadPlanCallFunctionUsingABI failed");
+ error.SetErrorString("ThreadPlanCallFunctionUsingABI failed");
return false;
}
@@ -1511,7 +1511,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
// Check if the return value is valid
if (vobj == nullptr || !retVal) {
error.SetErrorToGenericError();
- error.SetErrorStringWithFormat("unable to get the return value");
+ error.SetErrorString("unable to get the return value");
return false;
}
diff --git a/contrib/llvm-project/lldb/source/Expression/Materializer.cpp b/contrib/llvm-project/lldb/source/Expression/Materializer.cpp
index f33462053f22..a93c127dd0d0 100644
--- a/contrib/llvm-project/lldb/source/Expression/Materializer.cpp
+++ b/contrib/llvm-project/lldb/source/Expression/Materializer.cpp
@@ -67,7 +67,7 @@ public:
const bool zero_memory = false;
lldb::addr_t mem = map.Malloc(
- m_persistent_variable_sp->GetByteSize(), 8,
+ m_persistent_variable_sp->GetByteSize().getValueOr(0), 8,
lldb::ePermissionsReadable | lldb::ePermissionsWritable,
IRMemoryMap::eAllocationPolicyMirror, zero_memory, allocate_error);
@@ -106,7 +106,8 @@ public:
Status write_error;
map.WriteMemory(mem, m_persistent_variable_sp->GetValueBytes(),
- m_persistent_variable_sp->GetByteSize(), write_error);
+ m_persistent_variable_sp->GetByteSize().getValueOr(0),
+ write_error);
if (!write_error.Success()) {
err.SetErrorStringWithFormat(
@@ -234,7 +235,7 @@ public:
map.GetBestExecutionContextScope(),
m_persistent_variable_sp.get()->GetCompilerType(),
m_persistent_variable_sp->GetName(), location, eAddressTypeLoad,
- m_persistent_variable_sp->GetByteSize());
+ m_persistent_variable_sp->GetByteSize().getValueOr(0));
if (frame_top != LLDB_INVALID_ADDRESS &&
frame_bottom != LLDB_INVALID_ADDRESS && location >= frame_bottom &&
@@ -279,7 +280,8 @@ public:
LLDB_LOGF(log, "Dematerializing %s from 0x%" PRIx64 " (size = %llu)",
m_persistent_variable_sp->GetName().GetCString(),
(uint64_t)mem,
- (unsigned long long)m_persistent_variable_sp->GetByteSize());
+ (unsigned long long)m_persistent_variable_sp->GetByteSize()
+ .getValueOr(0));
// Read the contents of the spare memory area
@@ -288,7 +290,7 @@ public:
Status read_error;
map.ReadMemory(m_persistent_variable_sp->GetValueBytes(), mem,
- m_persistent_variable_sp->GetByteSize(), read_error);
+ m_persistent_variable_sp->GetByteSize().getValueOr(0), read_error);
if (!read_error.Success()) {
err.SetErrorStringWithFormat(
@@ -369,10 +371,11 @@ public:
if (!err.Success()) {
dump_stream.Printf(" <could not be read>\n");
} else {
- DataBufferHeap data(m_persistent_variable_sp->GetByteSize(), 0);
+ DataBufferHeap data(
+ m_persistent_variable_sp->GetByteSize().getValueOr(0), 0);
map.ReadMemory(data.GetBytes(), target_address,
- m_persistent_variable_sp->GetByteSize(), err);
+ m_persistent_variable_sp->GetByteSize().getValueOr(0), err);
if (!err.Success()) {
dump_stream.Printf(" <could not be read>\n");
@@ -514,7 +517,7 @@ public:
return;
}
- if (data.GetByteSize() < m_variable_sp->GetType()->GetByteSize()) {
+ if (data.GetByteSize() < m_variable_sp->GetType()->GetByteSize(scope)) {
if (data.GetByteSize() == 0 &&
!m_variable_sp->LocationExpression().IsValid()) {
err.SetErrorStringWithFormat("the variable '%s' has no location, "
@@ -525,7 +528,7 @@ public:
"size of variable %s (%" PRIu64
") is larger than the ValueObject's size (%" PRIu64 ")",
m_variable_sp->GetName().AsCString(),
- m_variable_sp->GetType()->GetByteSize().getValueOr(0),
+ m_variable_sp->GetType()->GetByteSize(scope).getValueOr(0),
data.GetByteSize());
}
return;
@@ -621,8 +624,8 @@ public:
Status extract_error;
- map.GetMemoryData(data, m_temporary_allocation, valobj_sp->GetByteSize(),
- extract_error);
+ map.GetMemoryData(data, m_temporary_allocation,
+ valobj_sp->GetByteSize().getValueOr(0), extract_error);
if (!extract_error.Success()) {
err.SetErrorStringWithFormat("couldn't get the data for variable %s",
@@ -797,7 +800,7 @@ public:
llvm::Optional<size_t> opt_bit_align = m_type.GetTypeBitAlign(exe_scope);
if (!opt_bit_align) {
- err.SetErrorStringWithFormat("can't get the type alignment");
+ err.SetErrorString("can't get the type alignment");
return;
}
@@ -919,7 +922,7 @@ public:
ret->ValueUpdated();
- const size_t pvar_byte_size = ret->GetByteSize();
+ const size_t pvar_byte_size = ret->GetByteSize().getValueOr(0);
uint8_t *pvar_data = ret->GetValueBytes();
map.ReadMemory(pvar_data, address, pvar_byte_size, read_error);
@@ -1279,9 +1282,8 @@ public:
m_register_contents.reset();
- RegisterValue register_value(
- const_cast<uint8_t *>(register_data.GetDataStart()),
- register_data.GetByteSize(), register_data.GetByteOrder());
+ RegisterValue register_value(register_data.GetData(),
+ register_data.GetByteOrder());
if (!reg_context_sp->WriteRegister(&m_register_info, register_value)) {
err.SetErrorStringWithFormat("couldn't write the value of register %s",
diff --git a/contrib/llvm-project/lldb/source/Expression/REPL.cpp b/contrib/llvm-project/lldb/source/Expression/REPL.cpp
index fd7c39686921..c3d14960f74c 100644
--- a/contrib/llvm-project/lldb/source/Expression/REPL.cpp
+++ b/contrib/llvm-project/lldb/source/Expression/REPL.cpp
@@ -123,10 +123,11 @@ const char *REPL::IOHandlerGetHelpPrologue() {
"Valid statements, expressions, and declarations are immediately "
"compiled and executed.\n\n"
"The complete set of LLDB debugging commands are also available as "
- "described below. Commands "
+ "described below.\n\nCommands "
"must be prefixed with a colon at the REPL prompt (:quit for "
"example.) Typing just a colon "
- "followed by return will switch to the LLDB prompt.\n\n";
+ "followed by return will switch to the LLDB prompt.\n\n"
+ "Type “< path” to read in code from a text file “path”.\n\n";
}
bool REPL::IOHandlerIsInputComplete(IOHandler &io_handler, StringList &lines) {
@@ -179,6 +180,36 @@ int REPL::IOHandlerFixIndentation(IOHandler &io_handler,
return (int)desired_indent - actual_indent;
}
+static bool ReadCode(const std::string &path, std::string &code,
+ lldb::StreamFileSP &error_sp) {
+ auto &fs = FileSystem::Instance();
+ llvm::Twine pathTwine(path);
+ if (!fs.Exists(pathTwine)) {
+ error_sp->Printf("no such file at path '%s'\n", path.c_str());
+ return false;
+ }
+ if (!fs.Readable(pathTwine)) {
+ error_sp->Printf("could not read file at path '%s'\n", path.c_str());
+ return false;
+ }
+ const size_t file_size = fs.GetByteSize(pathTwine);
+ const size_t max_size = code.max_size();
+ if (file_size > max_size) {
+ error_sp->Printf("file at path '%s' too large: "
+ "file_size = %zu, max_size = %zu\n",
+ path.c_str(), file_size, max_size);
+ return false;
+ }
+ auto data_sp = fs.CreateDataBuffer(pathTwine);
+ if (data_sp == nullptr) {
+ error_sp->Printf("could not create buffer for file at path '%s'\n",
+ path.c_str());
+ return false;
+ }
+ code.assign((const char *)data_sp->GetBytes(), data_sp->GetByteSize());
+ return true;
+}
+
void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
lldb::StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
@@ -257,6 +288,15 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) {
}
}
} else {
+ if (code[0] == '<') {
+ // User wants to read code from a file.
+ // Interpret rest of line as a literal path.
+ auto path = llvm::StringRef(code.substr(1)).trim().str();
+ if (!ReadCode(path, code, error_sp)) {
+ return;
+ }
+ }
+
// Unwind any expression we might have been running in case our REPL
// expression crashed and the user was looking around
if (m_dedicated_repl_mode) {
diff --git a/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp b/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp
index 47d13f052bfb..5beed4657b37 100644
--- a/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp
+++ b/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp
@@ -358,6 +358,7 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx,
} else {
if (expr_result) {
result_valobj_sp = expr_result->GetValueObject();
+ result_valobj_sp->SetPreferredDisplayLanguage(language);
LLDB_LOG(log,
"== [UserExpression::Evaluate] Execution completed "
diff --git a/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp b/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp
index 3de2ee2acbbf..128db0ccbc3e 100644
--- a/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp
+++ b/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp
@@ -41,9 +41,9 @@ char UtilityFunction::ID;
/// \param[in] name
/// The name of the function, as used in the text.
UtilityFunction::UtilityFunction(ExecutionContextScope &exe_scope,
- const char *text, const char *name)
+ std::string text, std::string name)
: Expression(exe_scope), m_execution_unit_sp(), m_jit_module_wp(),
- m_function_text(), m_function_name(name) {}
+ m_function_text(std::move(text)), m_function_name(std::move(name)) {}
UtilityFunction::~UtilityFunction() {
lldb::ProcessSP process_sp(m_jit_process_wp.lock());
diff --git a/contrib/llvm-project/lldb/source/Host/common/Editline.cpp b/contrib/llvm-project/lldb/source/Host/common/Editline.cpp
index 226e638aba25..026a05da45b2 100644
--- a/contrib/llvm-project/lldb/source/Host/common/Editline.cpp
+++ b/contrib/llvm-project/lldb/source/Host/common/Editline.cpp
@@ -48,9 +48,12 @@ int setupterm(char *term, int fildes, int *errret);
// understand the relationship between DisplayInput(), MoveCursor(),
// SetCurrentLine(), and SaveEditedLine() before making changes.
+/// https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf
#define ESCAPE "\x1b"
+/// Faint, decreased intensity or second colour.
#define ANSI_FAINT ESCAPE "[2m"
-#define ANSI_UNFAINT ESCAPE "[22m"
+/// Normal colour or normal intensity (neither bold nor faint).
+#define ANSI_UNFAINT ESCAPE "[0m"
#define ANSI_CLEAR_BELOW ESCAPE "[J"
#define ANSI_CLEAR_RIGHT ESCAPE "[K"
#define ANSI_SET_COLUMN_N ESCAPE "[%dG"
@@ -207,7 +210,7 @@ private:
// Compute the history path lazily.
if (m_path.empty() && m_history && !m_prefix.empty()) {
llvm::SmallString<128> lldb_history_file;
- llvm::sys::path::home_directory(lldb_history_file);
+ FileSystem::Instance().GetHomeDirectory(lldb_history_file);
llvm::sys::path::append(lldb_history_file, ".lldb");
// LLDB stores its history in ~/.lldb/. If for some reason this directory
@@ -1001,11 +1004,15 @@ unsigned char Editline::TabCommand(int ch) {
case CompletionMode::Normal: {
std::string to_add = completion.GetCompletion();
to_add = to_add.substr(request.GetCursorArgumentPrefix().size());
- if (request.GetParsedArg().IsQuoted())
+ // Terminate the current argument with a quote if it started with a quote.
+ if (!request.GetParsedLine().empty() && request.GetParsedArg().IsQuoted())
to_add.push_back(request.GetParsedArg().GetQuoteChar());
to_add.push_back(' ');
el_insertstr(m_editline, to_add.c_str());
- break;
+ // Clear all the autosuggestion parts if the only single space can be completed.
+ if (to_add == " ")
+ return CC_REDISPLAY;
+ return CC_REFRESH;
}
case CompletionMode::Partial: {
std::string to_add = completion.GetCompletion();
@@ -1039,6 +1046,52 @@ unsigned char Editline::TabCommand(int ch) {
return CC_REDISPLAY;
}
+unsigned char Editline::ApplyAutosuggestCommand(int ch) {
+ const LineInfo *line_info = el_line(m_editline);
+ llvm::StringRef line(line_info->buffer,
+ line_info->lastchar - line_info->buffer);
+
+ if (llvm::Optional<std::string> to_add =
+ m_suggestion_callback(line, m_suggestion_callback_baton))
+ el_insertstr(m_editline, to_add->c_str());
+
+ return CC_REDISPLAY;
+}
+
+unsigned char Editline::TypedCharacter(int ch) {
+ std::string typed = std::string(1, ch);
+ el_insertstr(m_editline, typed.c_str());
+ const LineInfo *line_info = el_line(m_editline);
+ llvm::StringRef line(line_info->buffer,
+ line_info->lastchar - line_info->buffer);
+
+ if (llvm::Optional<std::string> to_add =
+ m_suggestion_callback(line, m_suggestion_callback_baton)) {
+ std::string to_add_color = ANSI_FAINT + to_add.getValue() + ANSI_UNFAINT;
+ fputs(typed.c_str(), m_output_file);
+ fputs(to_add_color.c_str(), m_output_file);
+ size_t new_autosuggestion_size = line.size() + to_add->length();
+ // Print spaces to hide any remains of a previous longer autosuggestion.
+ if (new_autosuggestion_size < m_previous_autosuggestion_size) {
+ size_t spaces_to_print =
+ m_previous_autosuggestion_size - new_autosuggestion_size;
+ std::string spaces = std::string(spaces_to_print, ' ');
+ fputs(spaces.c_str(), m_output_file);
+ }
+ m_previous_autosuggestion_size = new_autosuggestion_size;
+
+ int editline_cursor_position =
+ (int)((line_info->cursor - line_info->buffer) + GetPromptWidth());
+ int editline_cursor_row = editline_cursor_position / m_terminal_width;
+ int toColumn =
+ editline_cursor_position - (editline_cursor_row * m_terminal_width);
+ fprintf(m_output_file, ANSI_SET_COLUMN_N, toColumn);
+ return CC_REFRESH;
+ }
+
+ return CC_REDISPLAY;
+}
+
void Editline::ConfigureEditor(bool multiline) {
if (m_editline && m_multiline_enabled == multiline)
return;
@@ -1152,7 +1205,38 @@ void Editline::ConfigureEditor(bool multiline) {
if (!multiline) {
el_set(m_editline, EL_BIND, "^r", "em-inc-search-prev",
NULL); // Cycle through backwards search, entering string
+
+ if (m_suggestion_callback) {
+ el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-apply-complete"),
+ EditLineConstString("Adopt autocompletion"),
+ (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
+ return Editline::InstanceFor(editline)->ApplyAutosuggestCommand(
+ ch);
+ }));
+
+ el_set(m_editline, EL_BIND, "^f", "lldb-apply-complete",
+ NULL); // Apply a part that is suggested automatically
+
+ el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-typed-character"),
+ EditLineConstString("Typed character"),
+ (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
+ return Editline::InstanceFor(editline)->TypedCharacter(ch);
+ }));
+
+ char bind_key[2] = {0, 0};
+ llvm::StringRef ascii_chars =
+ "abcdefghijklmnopqrstuvwxzyABCDEFGHIJKLMNOPQRSTUVWXZY1234567890!\"#$%"
+ "&'()*+,./:;<=>?@[]_`{|}~ ";
+ for (char c : ascii_chars) {
+ bind_key[0] = c;
+ el_set(m_editline, EL_BIND, bind_key, "lldb-typed-character", NULL);
+ }
+ el_set(m_editline, EL_BIND, "\\-", "lldb-typed-character", NULL);
+ el_set(m_editline, EL_BIND, "\\^", "lldb-typed-character", NULL);
+ el_set(m_editline, EL_BIND, "\\\\", "lldb-typed-character", NULL);
+ }
}
+
el_set(m_editline, EL_BIND, "^w", "ed-delete-prev-word",
NULL); // Delete previous word, behave like bash in emacs mode
el_set(m_editline, EL_BIND, "\t", "lldb-complete",
@@ -1363,6 +1447,12 @@ bool Editline::Cancel() {
return result;
}
+void Editline::SetSuggestionCallback(SuggestionCallbackType callback,
+ void *baton) {
+ m_suggestion_callback = callback;
+ m_suggestion_callback_baton = baton;
+}
+
void Editline::SetAutoCompleteCallback(CompleteCallbackType callback,
void *baton) {
m_completion_callback = callback;
diff --git a/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp b/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp
index 0fa27d131e1a..9fa8854d950e 100644
--- a/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp
+++ b/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp
@@ -49,7 +49,7 @@ void FileSystem::Initialize() {
InstanceImpl().emplace();
}
-void FileSystem::Initialize(std::shared_ptr<FileCollector> collector) {
+void FileSystem::Initialize(std::shared_ptr<FileCollectorBase> collector) {
lldbassert(!InstanceImpl() && "Already initialized.");
InstanceImpl().emplace(collector);
}
@@ -360,6 +360,22 @@ bool FileSystem::ResolveExecutableLocation(FileSpec &file_spec) {
return true;
}
+bool FileSystem::GetHomeDirectory(SmallVectorImpl<char> &path) const {
+ if (!m_home_directory.empty()) {
+ path.assign(m_home_directory.begin(), m_home_directory.end());
+ return true;
+ }
+ return llvm::sys::path::home_directory(path);
+}
+
+bool FileSystem::GetHomeDirectory(FileSpec &file_spec) const {
+ SmallString<128> home_dir;
+ if (!GetHomeDirectory(home_dir))
+ return false;
+ file_spec.SetPath(home_dir);
+ return true;
+}
+
static int OpenWithFS(const FileSystem &fs, const char *path, int flags,
int mode) {
return const_cast<FileSystem &>(fs).Open(path, flags, mode);
@@ -463,7 +479,7 @@ ErrorOr<std::string> FileSystem::GetExternalPath(const llvm::Twine &path) {
// If VFS mapped we know the underlying FS is a RedirectingFileSystem.
ErrorOr<vfs::RedirectingFileSystem::Entry *> E =
- static_cast<vfs::RedirectingFileSystem &>(*m_fs).lookupPath(path);
+ static_cast<vfs::RedirectingFileSystem &>(*m_fs).lookupPath(path.str());
if (!E) {
if (E.getError() == llvm::errc::no_such_file_or_directory) {
return path.str();
@@ -495,3 +511,7 @@ void FileSystem::Collect(const llvm::Twine &file) {
else
m_collector->addFile(file);
}
+
+void FileSystem::SetHomeDirectory(std::string home_directory) {
+ m_home_directory = std::move(home_directory);
+}
diff --git a/contrib/llvm-project/lldb/source/Host/common/Host.cpp b/contrib/llvm-project/lldb/source/Host/common/Host.cpp
index 4128fa19c142..99316660908e 100644
--- a/contrib/llvm-project/lldb/source/Host/common/Host.cpp
+++ b/contrib/llvm-project/lldb/source/Host/common/Host.cpp
@@ -60,6 +60,7 @@
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Predicate.h"
+#include "lldb/Utility/ReproducerProvider.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-private-forward.h"
#include "llvm/ADT/SmallString.h"
@@ -466,14 +467,24 @@ MonitorShellCommand(std::shared_ptr<ShellInfo> shell_info, lldb::pid_t pid,
return true;
}
-Status Host::RunShellCommand(const char *command, const FileSpec &working_dir,
- int *status_ptr, int *signo_ptr,
- std::string *command_output_ptr,
+Status Host::RunShellCommand(llvm::StringRef command,
+ const FileSpec &working_dir, int *status_ptr,
+ int *signo_ptr, std::string *command_output_ptr,
+ const Timeout<std::micro> &timeout,
+ bool run_in_shell, bool hide_stderr) {
+ return RunShellCommand(llvm::StringRef(), Args(command), working_dir,
+ status_ptr, signo_ptr, command_output_ptr, timeout,
+ run_in_shell, hide_stderr);
+}
+
+Status Host::RunShellCommand(llvm::StringRef shell_path,
+ llvm::StringRef command,
+ const FileSpec &working_dir, int *status_ptr,
+ int *signo_ptr, std::string *command_output_ptr,
const Timeout<std::micro> &timeout,
- bool run_in_default_shell,
- bool hide_stderr) {
- return RunShellCommand(Args(command), working_dir, status_ptr, signo_ptr,
- command_output_ptr, timeout, run_in_default_shell,
+ bool run_in_shell, bool hide_stderr) {
+ return RunShellCommand(shell_path, Args(command), working_dir, status_ptr,
+ signo_ptr, command_output_ptr, timeout, run_in_shell,
hide_stderr);
}
@@ -481,20 +492,32 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
int *status_ptr, int *signo_ptr,
std::string *command_output_ptr,
const Timeout<std::micro> &timeout,
- bool run_in_default_shell,
- bool hide_stderr) {
+ bool run_in_shell, bool hide_stderr) {
+ return RunShellCommand(llvm::StringRef(), args, working_dir, status_ptr,
+ signo_ptr, command_output_ptr, timeout, run_in_shell,
+ hide_stderr);
+}
+
+Status Host::RunShellCommand(llvm::StringRef shell_path, const Args &args,
+ const FileSpec &working_dir, int *status_ptr,
+ int *signo_ptr, std::string *command_output_ptr,
+ const Timeout<std::micro> &timeout,
+ bool run_in_shell, bool hide_stderr) {
Status error;
ProcessLaunchInfo launch_info;
launch_info.SetArchitecture(HostInfo::GetArchitecture());
- if (run_in_default_shell) {
+ if (run_in_shell) {
// Run the command in a shell
- launch_info.SetShell(HostInfo::GetDefaultShell());
+ FileSpec shell = HostInfo::GetDefaultShell();
+ if (!shell_path.empty())
+ shell.SetPath(shell_path);
+
+ launch_info.SetShell(shell);
launch_info.GetArguments().AppendArguments(args);
- const bool localhost = true;
const bool will_debug = false;
const bool first_arg_is_full_shell_command = false;
launch_info.ConvertArgumentsForLaunchingInShell(
- error, localhost, will_debug, first_arg_is_full_shell_command, 0);
+ error, will_debug, first_arg_is_full_shell_command, 0);
} else {
// No shell, just run it
const bool first_arg_is_executable = true;
diff --git a/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp b/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp
index a4d0b4181d58..070fda664678 100644
--- a/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp
+++ b/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp
@@ -298,8 +298,7 @@ Status NativeProcessProtocol::RemoveHardwareBreakpoint(lldb::addr_t addr) {
bool NativeProcessProtocol::RegisterNativeDelegate(
NativeDelegate &native_delegate) {
std::lock_guard<std::recursive_mutex> guard(m_delegates_mutex);
- if (std::find(m_delegates.begin(), m_delegates.end(), &native_delegate) !=
- m_delegates.end())
+ if (llvm::is_contained(m_delegates, &native_delegate))
return false;
m_delegates.push_back(&native_delegate);
@@ -523,7 +522,8 @@ NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
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_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
+ static const uint8_t g_ppc_opcode[] = {0x7f, 0xe0, 0x00, 0x08}; // trap
+ static const uint8_t g_ppcle_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
switch (GetArchitecture().GetMachine()) {
case llvm::Triple::aarch64:
@@ -545,8 +545,12 @@ NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
case llvm::Triple::systemz:
return llvm::makeArrayRef(g_s390x_opcode);
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ return llvm::makeArrayRef(g_ppc_opcode);
+
case llvm::Triple::ppc64le:
- return llvm::makeArrayRef(g_ppc64le_opcode);
+ return llvm::makeArrayRef(g_ppcle_opcode);
default:
return llvm::createStringError(llvm::inconvertibleErrorCode(),
@@ -569,6 +573,8 @@ size_t NativeProcessProtocol::GetSoftwareBreakpointPCOffset() {
case llvm::Triple::mips64el:
case llvm::Triple::mips:
case llvm::Triple::mipsel:
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
case llvm::Triple::ppc64le:
// On these architectures the PC doesn't get updated for breakpoint hits.
return 0;
diff --git a/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp b/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp
index 47548f90491d..9bb877fff878 100644
--- a/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp
+++ b/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp
@@ -266,6 +266,10 @@ bool NativeRegisterContext::ClearHardwareWatchpoint(uint32_t hw_index) {
return false;
}
+Status NativeRegisterContext::ClearWatchpointHit(uint32_t hw_index) {
+ return Status("not implemented");
+}
+
Status NativeRegisterContext::ClearAllHardwareWatchpoints() {
return Status("not implemented");
}
@@ -420,3 +424,32 @@ NativeRegisterContext::ConvertRegisterKindToRegisterNumber(uint32_t kind,
return LLDB_INVALID_REGNUM;
}
+
+std::vector<uint32_t>
+NativeRegisterContext::GetExpeditedRegisters(ExpeditedRegs expType) const {
+ if (expType == ExpeditedRegs::Minimal) {
+ // Expedite only a minimum set of important generic registers.
+ static const uint32_t k_expedited_registers[] = {
+ LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_SP, LLDB_REGNUM_GENERIC_FP,
+ LLDB_REGNUM_GENERIC_RA};
+
+ std::vector<uint32_t> expedited_reg_nums;
+ for (uint32_t gen_reg : k_expedited_registers) {
+ uint32_t reg_num =
+ ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, gen_reg);
+ if (reg_num == LLDB_INVALID_REGNUM)
+ continue; // Target does not support the given register.
+ else
+ expedited_reg_nums.push_back(reg_num);
+ }
+
+ return expedited_reg_nums;
+ }
+
+ if (GetRegisterSetCount() > 0 && expType == ExpeditedRegs::Full)
+ return std::vector<uint32_t>(GetRegisterSet(0)->registers,
+ GetRegisterSet(0)->registers +
+ GetRegisterSet(0)->num_registers);
+
+ return std::vector<uint32_t>();
+}
diff --git a/contrib/llvm-project/lldb/source/Host/common/OptionParser.cpp b/contrib/llvm-project/lldb/source/Host/common/OptionParser.cpp
index b5c7ea66732c..0274fdc4ac3f 100644
--- a/contrib/llvm-project/lldb/source/Host/common/OptionParser.cpp
+++ b/contrib/llvm-project/lldb/source/Host/common/OptionParser.cpp
@@ -8,6 +8,7 @@
#include "lldb/Host/OptionParser.h"
#include "lldb/Host/HostGetOpt.h"
+#include "lldb/Utility/OptionDefinition.h"
#include "lldb/lldb-private-types.h"
#include <vector>
diff --git a/contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp b/contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp
index 4bc8cda7a006..1b4b2c6c3ac2 100644
--- a/contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp
+++ b/contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp
@@ -218,11 +218,10 @@ llvm::Error ProcessLaunchInfo::SetUpPtyRedirection() {
// do for now.
open_flags |= O_CLOEXEC;
#endif
- if (!m_pty->OpenFirstAvailablePrimary(open_flags, nullptr, 0)) {
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "PTY::OpenFirstAvailablePrimary failed");
- }
- const FileSpec secondary_file_spec(m_pty->GetSecondaryName(nullptr, 0));
+ if (llvm::Error Err = m_pty->OpenFirstAvailablePrimary(open_flags))
+ return Err;
+
+ const FileSpec secondary_file_spec(m_pty->GetSecondaryName());
// Only use the secondary tty if we don't have anything specified for
// input and don't have an action for stdin
@@ -242,8 +241,8 @@ llvm::Error ProcessLaunchInfo::SetUpPtyRedirection() {
}
bool ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell(
- Status &error, bool localhost, bool will_debug,
- bool first_arg_is_full_shell_command, int32_t num_resumes) {
+ Status &error, bool will_debug, bool first_arg_is_full_shell_command,
+ uint32_t num_resumes) {
error.Clear();
if (GetFlags().Test(eLaunchFlagLaunchInShell)) {
@@ -254,7 +253,6 @@ bool ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell(
if (argv == nullptr || argv[0] == nullptr)
return false;
Args shell_arguments;
- std::string safe_arg;
shell_arguments.AppendArgument(shell_executable);
const llvm::Triple &triple = GetArchitecture().GetTriple();
if (triple.getOS() == llvm::Triple::Win32 &&
@@ -331,9 +329,10 @@ bool ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell(
return false;
} else {
for (size_t i = 0; argv[i] != nullptr; ++i) {
- const char *arg =
- Args::GetShellSafeArgument(m_shell, argv[i], safe_arg);
- shell_command.Printf(" %s", arg);
+ std::string safe_arg = Args::GetShellSafeArgument(m_shell, argv[i]);
+ // Add a space to separate this arg from the previous one.
+ shell_command.PutCString(" ");
+ shell_command.PutCString(safe_arg);
}
}
shell_arguments.AppendArgument(shell_command.GetString());
diff --git a/contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp b/contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp
index 72549f1c88ab..de76e8ab4f68 100644
--- a/contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp
+++ b/contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp
@@ -8,9 +8,11 @@
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Host/Config.h"
-
+#include "llvm/Support/Errc.h"
#include "llvm/Support/Errno.h"
-
+#include <cassert>
+#include <limits.h>
+#include <mutex>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -26,12 +28,6 @@ int posix_openpt(int flags);
using namespace lldb_private;
-// Write string describing error number
-static void ErrnoToStr(char *error_str, size_t error_len) {
- std::string strerror = llvm::sys::StrError();
- ::snprintf(error_str, error_len, "%s", strerror.c_str());
-}
-
// PseudoTerminal constructor
PseudoTerminal::PseudoTerminal()
: m_primary_fd(invalid_fd), m_secondary_fd(invalid_fd) {}
@@ -63,190 +59,106 @@ void PseudoTerminal::CloseSecondaryFileDescriptor() {
}
}
-// Open the first available pseudo terminal with OFLAG as the permissions. The
-// file descriptor is stored in this object and can be accessed with the
-// PrimaryFileDescriptor() accessor. The ownership of the primary file
-// descriptor can be released using the ReleasePrimaryFileDescriptor() accessor.
-// If this object has a valid primary files descriptor when its destructor is
-// called, it will close the primary file descriptor, therefore clients must
-// call ReleasePrimaryFileDescriptor() if they wish to use the primary file
-// descriptor after this object is out of scope or destroyed.
-//
-// RETURNS:
-// True when successful, false indicating an error occurred.
-bool PseudoTerminal::OpenFirstAvailablePrimary(int oflag, char *error_str,
- size_t error_len) {
- if (error_str)
- error_str[0] = '\0';
-
+llvm::Error PseudoTerminal::OpenFirstAvailablePrimary(int oflag) {
#if LLDB_ENABLE_POSIX
// Open the primary side of a pseudo terminal
m_primary_fd = ::posix_openpt(oflag);
if (m_primary_fd < 0) {
- if (error_str)
- ErrnoToStr(error_str, error_len);
- return false;
+ return llvm::errorCodeToError(
+ std::error_code(errno, std::generic_category()));
}
// Grant access to the secondary pseudo terminal
if (::grantpt(m_primary_fd) < 0) {
- if (error_str)
- ErrnoToStr(error_str, error_len);
+ std::error_code EC(errno, std::generic_category());
ClosePrimaryFileDescriptor();
- return false;
+ return llvm::errorCodeToError(EC);
}
// Clear the lock flag on the secondary pseudo terminal
if (::unlockpt(m_primary_fd) < 0) {
- if (error_str)
- ErrnoToStr(error_str, error_len);
+ std::error_code EC(errno, std::generic_category());
ClosePrimaryFileDescriptor();
- return false;
+ return llvm::errorCodeToError(EC);
}
- return true;
+ return llvm::Error::success();
#else
- if (error_str)
- ::snprintf(error_str, error_len, "%s", "pseudo terminal not supported");
- return false;
+ return llvm::errorCodeToError(llvm::errc::not_supported);
#endif
}
-// Open the secondary pseudo terminal for the current primary pseudo terminal. A
-// primary pseudo terminal should already be valid prior to calling this
-// function (see OpenFirstAvailablePrimary()). The file descriptor is stored
-// this object's member variables and can be accessed via the
-// GetSecondaryFileDescriptor(), or released using the
-// ReleaseSecondaryFileDescriptor() member function.
-//
-// RETURNS:
-// True when successful, false indicating an error occurred.
-bool PseudoTerminal::OpenSecondary(int oflag, char *error_str,
- size_t error_len) {
- if (error_str)
- error_str[0] = '\0';
-
+llvm::Error PseudoTerminal::OpenSecondary(int oflag) {
CloseSecondaryFileDescriptor();
- // Open the primary side of a pseudo terminal
- const char *secondary_name = GetSecondaryName(error_str, error_len);
-
- if (secondary_name == nullptr)
- return false;
-
- m_secondary_fd =
- llvm::sys::RetryAfterSignal(-1, ::open, secondary_name, oflag);
-
- if (m_secondary_fd < 0) {
- if (error_str)
- ErrnoToStr(error_str, error_len);
- return false;
- }
+ std::string name = GetSecondaryName();
+ m_secondary_fd = llvm::sys::RetryAfterSignal(-1, ::open, name.c_str(), oflag);
+ if (m_secondary_fd >= 0)
+ return llvm::Error::success();
- return true;
+ return llvm::errorCodeToError(
+ std::error_code(errno, std::generic_category()));
}
-// Get the name of the secondary pseudo terminal. A primary pseudo terminal
-// should already be valid prior to calling this function (see
-// OpenFirstAvailablePrimary()).
-//
-// RETURNS:
-// NULL if no valid primary pseudo terminal or if ptsname() fails.
-// The name of the secondary pseudo terminal as a NULL terminated C string
-// that comes from static memory, so a copy of the string should be
-// made as subsequent calls can change this value.
-const char *PseudoTerminal::GetSecondaryName(char *error_str,
- size_t error_len) const {
- if (error_str)
- error_str[0] = '\0';
-
- if (m_primary_fd < 0) {
- if (error_str)
- ::snprintf(error_str, error_len, "%s",
- "primary file descriptor is invalid");
- return nullptr;
- }
- const char *secondary_name = ::ptsname(m_primary_fd);
-
- if (error_str && secondary_name == nullptr)
- ErrnoToStr(error_str, error_len);
-
- return secondary_name;
+std::string PseudoTerminal::GetSecondaryName() const {
+ assert(m_primary_fd >= 0);
+#if HAVE_PTSNAME_R
+ char buf[PATH_MAX];
+ buf[0] = '\0';
+ int r = ptsname_r(m_primary_fd, buf, sizeof(buf));
+ (void)r;
+ assert(r == 0);
+ return buf;
+#else
+ static std::mutex mutex;
+ std::lock_guard<std::mutex> guard(mutex);
+ const char *r = ptsname(m_primary_fd);
+ assert(r != nullptr);
+ return r;
+#endif
}
-// Fork a child process and have its stdio routed to a pseudo terminal.
-//
-// In the parent process when a valid pid is returned, the primary file
-// descriptor can be used as a read/write access to stdio of the child process.
-//
-// In the child process the stdin/stdout/stderr will already be routed to the
-// secondary pseudo terminal and the primary file descriptor will be closed as
-// it is no longer needed by the child process.
-//
-// This class will close the file descriptors for the primary/secondary when the
-// destructor is called, so be sure to call ReleasePrimaryFileDescriptor() or
-// ReleaseSecondaryFileDescriptor() if any file descriptors are going to be used
-// past the lifespan of this object.
-//
-// RETURNS:
-// in the parent process: the pid of the child, or -1 if fork fails
-// in the child process: zero
-lldb::pid_t PseudoTerminal::Fork(char *error_str, size_t error_len) {
- if (error_str)
- error_str[0] = '\0';
- pid_t pid = LLDB_INVALID_PROCESS_ID;
+llvm::Expected<lldb::pid_t> PseudoTerminal::Fork() {
#if LLDB_ENABLE_POSIX
- int flags = O_RDWR;
- flags |= O_CLOEXEC;
- if (OpenFirstAvailablePrimary(flags, error_str, error_len)) {
- // Successfully opened our primary pseudo terminal
+ if (llvm::Error Err = OpenFirstAvailablePrimary(O_RDWR | O_CLOEXEC))
+ return std::move(Err);
+
+ pid_t pid = ::fork();
+ if (pid < 0) {
+ return llvm::errorCodeToError(
+ std::error_code(errno, std::generic_category()));
+ }
+ if (pid > 0) {
+ // Parent process.
+ return pid;
+ }
- pid = ::fork();
- if (pid < 0) {
- // Fork failed
- if (error_str)
- ErrnoToStr(error_str, error_len);
- } else if (pid == 0) {
- // Child Process
- ::setsid();
+ // Child Process
+ ::setsid();
- if (OpenSecondary(O_RDWR, error_str, error_len)) {
- // Successfully opened secondary
+ if (llvm::Error Err = OpenSecondary(O_RDWR))
+ return std::move(Err);
- // Primary FD should have O_CLOEXEC set, but let's close it just in
- // case...
- ClosePrimaryFileDescriptor();
+ // Primary FD should have O_CLOEXEC set, but let's close it just in
+ // case...
+ ClosePrimaryFileDescriptor();
#if defined(TIOCSCTTY)
- // Acquire the controlling terminal
- if (::ioctl(m_secondary_fd, TIOCSCTTY, (char *)0) < 0) {
- if (error_str)
- ErrnoToStr(error_str, error_len);
- }
+ // Acquire the controlling terminal
+ if (::ioctl(m_secondary_fd, TIOCSCTTY, (char *)0) < 0) {
+ return llvm::errorCodeToError(
+ std::error_code(errno, std::generic_category()));
+ }
#endif
- // Duplicate all stdio file descriptors to the secondary pseudo terminal
- if (::dup2(m_secondary_fd, STDIN_FILENO) != STDIN_FILENO) {
- if (error_str && !error_str[0])
- ErrnoToStr(error_str, error_len);
- }
-
- if (::dup2(m_secondary_fd, STDOUT_FILENO) != STDOUT_FILENO) {
- if (error_str && !error_str[0])
- ErrnoToStr(error_str, error_len);
- }
-
- if (::dup2(m_secondary_fd, STDERR_FILENO) != STDERR_FILENO) {
- if (error_str && !error_str[0])
- ErrnoToStr(error_str, error_len);
- }
- }
- } else {
- // Parent Process
- // Do nothing and let the pid get returned!
+ // Duplicate all stdio file descriptors to the secondary pseudo terminal
+ for (int fd : {STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO}) {
+ if (::dup2(m_secondary_fd, fd) != fd) {
+ return llvm::errorCodeToError(
+ std::error_code(errno, std::generic_category()));
}
}
#endif
- return pid;
+ return 0;
}
// The primary file descriptor accessor. This object retains ownership of the
diff --git a/contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp b/contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp
index 047cb0e4c2bf..ea7377edbd45 100644
--- a/contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp
+++ b/contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp
@@ -247,7 +247,7 @@ Status TCPSocket::Listen(llvm::StringRef name, int backlog) {
void TCPSocket::CloseListenSockets() {
for (auto socket : m_listen_sockets)
- CLOSE_SOCKET(socket.first);
+ CLOSE_SOCKET(socket.first);
m_listen_sockets.clear();
}
diff --git a/contrib/llvm-project/lldb/source/Host/freebsd/Host.cpp b/contrib/llvm-project/lldb/source/Host/freebsd/Host.cpp
index 09547e48afa9..c0cc74a5f6cc 100644
--- a/contrib/llvm-project/lldb/source/Host/freebsd/Host.cpp
+++ b/contrib/llvm-project/lldb/source/Host/freebsd/Host.cpp
@@ -83,6 +83,7 @@ GetFreeBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
match_info_ptr->GetProcessInfo().GetName())))
return false;
+ process_info.SetArg0(cstr);
Args &proc_args = process_info.GetArguments();
while (1) {
const uint8_t *p = data.PeekData(offset, 1);
@@ -175,6 +176,9 @@ uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc));
+ ProcessInstanceInfoMatch match_info_noname{match_info};
+ match_info_noname.SetNameMatchType(NameMatch::Ignore);
+
for (size_t i = 0; i < actual_pid_count; i++) {
const struct kinfo_proc &kinfo = kinfos[i];
@@ -212,7 +216,7 @@ uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
process_info.SetEffectiveGroupID(kinfo.ki_svgid);
// Make sure our info matches before we go fetch the name and cpu type
- if (match_info.Matches(process_info) &&
+ if (match_info_noname.Matches(process_info) &&
GetFreeBSDProcessArgs(&match_info, process_info)) {
GetFreeBSDProcessCPUType(process_info);
if (match_info.Matches(process_info))
diff --git a/contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp b/contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp
index 4708fb45deed..1945f9f9052f 100644
--- a/contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp
@@ -200,6 +200,9 @@ uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
return 0;
}
+ ProcessInstanceInfoMatch match_info_noname{match_info};
+ match_info_noname.SetNameMatchType(NameMatch::Ignore);
+
for (int i = 0; i < nproc; i++) {
if (proc_kinfo[i].p_pid < 1)
continue; /* not valid */
@@ -220,7 +223,7 @@ uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
if (proc_kinfo[i].p_nlwps > 1) {
bool already_registered = false;
for (size_t pi = 0; pi < process_infos.size(); pi++) {
- if (process_infos[pi].GetProcessID() == proc_kinfo[i].p_pid) {
+ if ((::pid_t)process_infos[pi].GetProcessID() == proc_kinfo[i].p_pid) {
already_registered = true;
break;
}
@@ -237,7 +240,7 @@ uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
process_info.SetEffectiveUserID(proc_kinfo[i].p_uid);
process_info.SetEffectiveGroupID(proc_kinfo[i].p_gid);
// Make sure our info matches before we go fetch the name and cpu type
- if (match_info.Matches(process_info) &&
+ if (match_info_noname.Matches(process_info) &&
GetNetBSDProcessArgs(&match_info, process_info)) {
GetNetBSDProcessCPUType(process_info);
if (match_info.Matches(process_info))
diff --git a/contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp
index 780222dffbf8..7cd05a1ad2eb 100644
--- a/contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp
+++ b/contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp
@@ -117,7 +117,7 @@ Status PipePosix::CreateNew(llvm::StringRef name, bool child_process_inherit) {
return Status("Pipe is already opened");
Status error;
- if (::mkfifo(name.data(), 0660) != 0)
+ if (::mkfifo(name.str().c_str(), 0660) != 0)
error.SetErrorToErrno();
return error;
@@ -138,8 +138,8 @@ Status PipePosix::CreateWithUniqueName(llvm::StringRef prefix,
// try again.
Status error;
do {
- llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath(),
- named_pipe_path);
+ llvm::sys::fs::createUniquePath(tmpdir_file_spec.GetPath(), named_pipe_path,
+ /*MakeAbsolute=*/false);
error = CreateNew(named_pipe_path, child_process_inherit);
} while (error.GetError() == EEXIST);
@@ -158,7 +158,7 @@ Status PipePosix::OpenAsReader(llvm::StringRef name,
flags |= O_CLOEXEC;
Status error;
- int fd = llvm::sys::RetryAfterSignal(-1, ::open, name.data(), flags);
+ int fd = llvm::sys::RetryAfterSignal(-1, ::open, name.str().c_str(), flags);
if (fd != -1)
m_fds[READ] = fd;
else
@@ -189,7 +189,7 @@ PipePosix::OpenAsWriterWithTimeout(llvm::StringRef name,
}
errno = 0;
- int fd = ::open(name.data(), flags);
+ int fd = ::open(name.str().c_str(), flags);
if (fd == -1) {
const auto errno_copy = errno;
// We may get ENXIO if a reader side of the pipe hasn't opened yet.
diff --git a/contrib/llvm-project/lldb/source/Initialization/SystemInitializerCommon.cpp b/contrib/llvm-project/lldb/source/Initialization/SystemInitializerCommon.cpp
index 0cef2a48dcb4..d9f69f57703c 100644
--- a/contrib/llvm-project/lldb/source/Initialization/SystemInitializerCommon.cpp
+++ b/contrib/llvm-project/lldb/source/Initialization/SystemInitializerCommon.cpp
@@ -14,7 +14,7 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Socket.h"
#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Reproducer.h"
+#include "lldb/Utility/ReproducerProvider.h"
#include "lldb/Utility/Timer.h"
#include "lldb/lldb-private.h"
@@ -39,6 +39,58 @@ SystemInitializerCommon::SystemInitializerCommon() {}
SystemInitializerCommon::~SystemInitializerCommon() {}
+/// Initialize the FileSystem based on the current reproducer mode.
+static llvm::Error InitializeFileSystem() {
+ auto &r = repro::Reproducer::Instance();
+ if (repro::Loader *loader = r.GetLoader()) {
+ FileSpec vfs_mapping = loader->GetFile<FileProvider::Info>();
+ if (vfs_mapping) {
+ if (llvm::Error e = FileSystem::Initialize(vfs_mapping))
+ return e;
+ } else {
+ FileSystem::Initialize();
+ }
+
+ // Set the current working directory form the reproducer.
+ llvm::Expected<std::string> working_dir =
+ repro::GetDirectoryFrom<WorkingDirectoryProvider>(loader);
+ if (!working_dir)
+ return working_dir.takeError();
+ if (std::error_code ec = FileSystem::Instance()
+ .GetVirtualFileSystem()
+ ->setCurrentWorkingDirectory(*working_dir)) {
+ return llvm::errorCodeToError(ec);
+ }
+
+ // Set the home directory from the reproducer.
+ llvm::Expected<std::string> home_dir =
+ repro::GetDirectoryFrom<HomeDirectoryProvider>(loader);
+ if (!home_dir)
+ return home_dir.takeError();
+ FileSystem::Instance().SetHomeDirectory(*home_dir);
+
+ return llvm::Error::success();
+ }
+
+ if (repro::Generator *g = r.GetGenerator()) {
+ repro::VersionProvider &vp = g->GetOrCreate<repro::VersionProvider>();
+ vp.SetVersion(lldb_private::GetVersion());
+
+ repro::FileProvider &fp = g->GetOrCreate<repro::FileProvider>();
+ FileSystem::Initialize(fp.GetFileCollector());
+
+ fp.RecordInterestingDirectory(
+ g->GetOrCreate<repro::WorkingDirectoryProvider>().GetDirectory());
+ fp.RecordInterestingDirectory(
+ g->GetOrCreate<repro::HomeDirectoryProvider>().GetDirectory());
+
+ return llvm::Error::success();
+ }
+
+ FileSystem::Initialize();
+ return llvm::Error::success();
+}
+
llvm::Error SystemInitializerCommon::Initialize() {
#if defined(_WIN32)
const char *disable_crash_dialog_var = getenv("LLDB_DISABLE_CRASH_DIALOG");
@@ -69,34 +121,8 @@ llvm::Error SystemInitializerCommon::Initialize() {
return e;
}
- auto &r = repro::Reproducer::Instance();
- if (repro::Loader *loader = r.GetLoader()) {
- FileSpec vfs_mapping = loader->GetFile<FileProvider::Info>();
- if (vfs_mapping) {
- if (llvm::Error e = FileSystem::Initialize(vfs_mapping))
- return e;
- } else {
- FileSystem::Initialize();
- }
- if (llvm::Expected<std::string> cwd =
- loader->LoadBuffer<WorkingDirectoryProvider>()) {
- llvm::StringRef working_dir = llvm::StringRef(*cwd).rtrim();
- if (std::error_code ec = FileSystem::Instance()
- .GetVirtualFileSystem()
- ->setCurrentWorkingDirectory(working_dir)) {
- return llvm::errorCodeToError(ec);
- }
- } else {
- return cwd.takeError();
- }
- } else if (repro::Generator *g = r.GetGenerator()) {
- repro::VersionProvider &vp = g->GetOrCreate<repro::VersionProvider>();
- vp.SetVersion(lldb_private::GetVersion());
- repro::FileProvider &fp = g->GetOrCreate<repro::FileProvider>();
- FileSystem::Initialize(fp.GetFileCollector());
- } else {
- FileSystem::Initialize();
- }
+ if (auto e = InitializeFileSystem())
+ return e;
Log::Initialize();
HostInfo::Initialize();
@@ -105,8 +131,7 @@ llvm::Error SystemInitializerCommon::Initialize() {
if (error)
return error;
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
process_gdb_remote::ProcessGDBRemoteLog::Initialize();
@@ -121,8 +146,7 @@ llvm::Error SystemInitializerCommon::Initialize() {
}
void SystemInitializerCommon::Terminate() {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
#if defined(_WIN32)
ProcessWindowsLog::Terminate();
diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp
index e55b25500179..fb503fe0afb0 100644
--- a/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp
+++ b/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp
@@ -6,14 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include <limits>
#include <memory>
#include <stdlib.h>
#include <string>
#include <vector>
-#include "CommandObjectScript.h"
-#include "lldb/Interpreter/CommandObjectRegexCommand.h"
-
#include "Commands/CommandObjectApropos.h"
#include "Commands/CommandObjectBreakpoint.h"
#include "Commands/CommandObjectCommands.h"
@@ -29,13 +27,17 @@
#include "Commands/CommandObjectPlugin.h"
#include "Commands/CommandObjectProcess.h"
#include "Commands/CommandObjectQuit.h"
+#include "Commands/CommandObjectRegexCommand.h"
#include "Commands/CommandObjectRegister.h"
#include "Commands/CommandObjectReproducer.h"
+#include "Commands/CommandObjectScript.h"
+#include "Commands/CommandObjectSession.h"
#include "Commands/CommandObjectSettings.h"
#include "Commands/CommandObjectSource.h"
#include "Commands/CommandObjectStats.h"
#include "Commands/CommandObjectTarget.h"
#include "Commands/CommandObjectThread.h"
+#include "Commands/CommandObjectTrace.h"
#include "Commands/CommandObjectType.h"
#include "Commands/CommandObjectVersion.h"
#include "Commands/CommandObjectWatchpoint.h"
@@ -44,6 +46,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"
@@ -52,6 +55,8 @@
#if LLDB_ENABLE_LIBEDIT
#include "lldb/Host/Editline.h"
#endif
+#include "lldb/Host/File.h"
+#include "lldb/Host/FileCache.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
@@ -63,6 +68,7 @@
#include "lldb/Interpreter/Property.h"
#include "lldb/Utility/Args.h"
+#include "lldb/Target/Language.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/TargetList.h"
@@ -74,6 +80,7 @@
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/ScopedPrinter.h"
using namespace lldb;
using namespace lldb_private;
@@ -116,7 +123,7 @@ CommandInterpreter::CommandInterpreter(Debugger &debugger,
m_skip_lldbinit_files(false), m_skip_app_init_files(false),
m_command_io_handler_sp(), m_comment_char('#'),
m_batch_command_mode(false), m_truncation_warning(eNoTruncation),
- m_command_source_depth(0), m_result() {
+ m_command_source_depth(0), m_result(), m_transcript_stream() {
SetEventName(eBroadcastBitThreadShouldExit, "thread-should-exit");
SetEventName(eBroadcastBitResetPrompt, "reset-prompt");
SetEventName(eBroadcastBitQuitCommandReceived, "quit");
@@ -142,6 +149,17 @@ void CommandInterpreter::SetPromptOnQuit(bool enable) {
m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, enable);
}
+bool CommandInterpreter::GetSaveSessionOnQuit() const {
+ const uint32_t idx = ePropertySaveSessionOnQuit;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
+}
+
+void CommandInterpreter::SetSaveSessionOnQuit(bool enable) {
+ const uint32_t idx = ePropertySaveSessionOnQuit;
+ m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, enable);
+}
+
bool CommandInterpreter::GetEchoCommands() const {
const uint32_t idx = ePropertyEchoCommands;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
@@ -206,8 +224,7 @@ bool CommandInterpreter::GetSpaceReplPrompts() const {
}
void CommandInterpreter::Initialize() {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
CommandReturnObject result(m_debugger.GetUseColor());
@@ -217,48 +234,48 @@ void CommandInterpreter::Initialize() {
OptionArgVectorSP alias_arguments_vector_sp(new OptionArgVector);
// Set up some initial aliases.
- CommandObjectSP cmd_obj_sp = GetCommandSPExact("quit", false);
+ CommandObjectSP cmd_obj_sp = GetCommandSPExact("quit");
if (cmd_obj_sp) {
AddAlias("q", cmd_obj_sp);
AddAlias("exit", cmd_obj_sp);
}
- cmd_obj_sp = GetCommandSPExact("_regexp-attach", false);
+ cmd_obj_sp = GetCommandSPExact("_regexp-attach");
if (cmd_obj_sp)
AddAlias("attach", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
- cmd_obj_sp = GetCommandSPExact("process detach", false);
+ cmd_obj_sp = GetCommandSPExact("process detach");
if (cmd_obj_sp) {
AddAlias("detach", cmd_obj_sp);
}
- cmd_obj_sp = GetCommandSPExact("process continue", false);
+ cmd_obj_sp = GetCommandSPExact("process continue");
if (cmd_obj_sp) {
AddAlias("c", cmd_obj_sp);
AddAlias("continue", cmd_obj_sp);
}
- cmd_obj_sp = GetCommandSPExact("_regexp-break", false);
+ cmd_obj_sp = GetCommandSPExact("_regexp-break");
if (cmd_obj_sp)
AddAlias("b", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
- cmd_obj_sp = GetCommandSPExact("_regexp-tbreak", false);
+ cmd_obj_sp = GetCommandSPExact("_regexp-tbreak");
if (cmd_obj_sp)
AddAlias("tbreak", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
- cmd_obj_sp = GetCommandSPExact("thread step-inst", false);
+ cmd_obj_sp = GetCommandSPExact("thread step-inst");
if (cmd_obj_sp) {
AddAlias("stepi", cmd_obj_sp);
AddAlias("si", cmd_obj_sp);
}
- cmd_obj_sp = GetCommandSPExact("thread step-inst-over", false);
+ cmd_obj_sp = GetCommandSPExact("thread step-inst-over");
if (cmd_obj_sp) {
AddAlias("nexti", cmd_obj_sp);
AddAlias("ni", cmd_obj_sp);
}
- cmd_obj_sp = GetCommandSPExact("thread step-in", false);
+ cmd_obj_sp = GetCommandSPExact("thread step-in");
if (cmd_obj_sp) {
AddAlias("s", cmd_obj_sp);
AddAlias("step", cmd_obj_sp);
@@ -272,86 +289,86 @@ void CommandInterpreter::Initialize() {
}
}
- cmd_obj_sp = GetCommandSPExact("thread step-over", false);
+ cmd_obj_sp = GetCommandSPExact("thread step-over");
if (cmd_obj_sp) {
AddAlias("n", cmd_obj_sp);
AddAlias("next", cmd_obj_sp);
}
- cmd_obj_sp = GetCommandSPExact("thread step-out", false);
+ cmd_obj_sp = GetCommandSPExact("thread step-out");
if (cmd_obj_sp) {
AddAlias("finish", cmd_obj_sp);
}
- cmd_obj_sp = GetCommandSPExact("frame select", false);
+ cmd_obj_sp = GetCommandSPExact("frame select");
if (cmd_obj_sp) {
AddAlias("f", cmd_obj_sp);
}
- cmd_obj_sp = GetCommandSPExact("thread select", false);
+ cmd_obj_sp = GetCommandSPExact("thread select");
if (cmd_obj_sp) {
AddAlias("t", cmd_obj_sp);
}
- cmd_obj_sp = GetCommandSPExact("_regexp-jump", false);
+ cmd_obj_sp = GetCommandSPExact("_regexp-jump");
if (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);
+ cmd_obj_sp = GetCommandSPExact("_regexp-list");
if (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);
+ cmd_obj_sp = GetCommandSPExact("_regexp-env");
if (cmd_obj_sp)
AddAlias("env", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
- cmd_obj_sp = GetCommandSPExact("memory read", false);
+ cmd_obj_sp = GetCommandSPExact("memory read");
if (cmd_obj_sp)
AddAlias("x", cmd_obj_sp);
- cmd_obj_sp = GetCommandSPExact("_regexp-up", false);
+ cmd_obj_sp = GetCommandSPExact("_regexp-up");
if (cmd_obj_sp)
AddAlias("up", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
- cmd_obj_sp = GetCommandSPExact("_regexp-down", false);
+ cmd_obj_sp = GetCommandSPExact("_regexp-down");
if (cmd_obj_sp)
AddAlias("down", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
- cmd_obj_sp = GetCommandSPExact("_regexp-display", false);
+ cmd_obj_sp = GetCommandSPExact("_regexp-display");
if (cmd_obj_sp)
AddAlias("display", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
- cmd_obj_sp = GetCommandSPExact("disassemble", false);
+ cmd_obj_sp = GetCommandSPExact("disassemble");
if (cmd_obj_sp)
AddAlias("dis", cmd_obj_sp);
- cmd_obj_sp = GetCommandSPExact("disassemble", false);
+ cmd_obj_sp = GetCommandSPExact("disassemble");
if (cmd_obj_sp)
AddAlias("di", cmd_obj_sp);
- cmd_obj_sp = GetCommandSPExact("_regexp-undisplay", false);
+ cmd_obj_sp = GetCommandSPExact("_regexp-undisplay");
if (cmd_obj_sp)
AddAlias("undisplay", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
- cmd_obj_sp = GetCommandSPExact("_regexp-bt", false);
+ cmd_obj_sp = GetCommandSPExact("_regexp-bt");
if (cmd_obj_sp)
AddAlias("bt", cmd_obj_sp)->SetSyntax(cmd_obj_sp->GetSyntax());
- cmd_obj_sp = GetCommandSPExact("target create", false);
+ cmd_obj_sp = GetCommandSPExact("target create");
if (cmd_obj_sp)
AddAlias("file", cmd_obj_sp);
- cmd_obj_sp = GetCommandSPExact("target modules", false);
+ cmd_obj_sp = GetCommandSPExact("target modules");
if (cmd_obj_sp)
AddAlias("image", cmd_obj_sp);
alias_arguments_vector_sp = std::make_shared<OptionArgVector>();
- cmd_obj_sp = GetCommandSPExact("expression", false);
+ cmd_obj_sp = GetCommandSPExact("expression");
if (cmd_obj_sp) {
AddAlias("p", cmd_obj_sp, "--")->SetHelpLong("");
AddAlias("print", cmd_obj_sp, "--")->SetHelpLong("");
@@ -381,7 +398,7 @@ void CommandInterpreter::Initialize() {
}
}
- cmd_obj_sp = GetCommandSPExact("platform shell", false);
+ cmd_obj_sp = GetCommandSPExact("platform shell");
if (cmd_obj_sp) {
CommandAlias *shell_alias = AddAlias("shell", cmd_obj_sp, " --host --");
if (shell_alias) {
@@ -391,12 +408,12 @@ void CommandInterpreter::Initialize() {
}
}
- cmd_obj_sp = GetCommandSPExact("process kill", false);
+ cmd_obj_sp = GetCommandSPExact("process kill");
if (cmd_obj_sp) {
AddAlias("kill", cmd_obj_sp);
}
- cmd_obj_sp = GetCommandSPExact("process launch", false);
+ cmd_obj_sp = GetCommandSPExact("process launch");
if (cmd_obj_sp) {
alias_arguments_vector_sp = std::make_shared<OptionArgVector>();
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
@@ -420,27 +437,32 @@ void CommandInterpreter::Initialize() {
#endif
}
- cmd_obj_sp = GetCommandSPExact("target symbols add", false);
+ cmd_obj_sp = GetCommandSPExact("target symbols add");
if (cmd_obj_sp) {
AddAlias("add-dsym", cmd_obj_sp);
}
- cmd_obj_sp = GetCommandSPExact("breakpoint set", false);
+ cmd_obj_sp = GetCommandSPExact("breakpoint set");
if (cmd_obj_sp) {
AddAlias("rbreak", cmd_obj_sp, "--func-regex %1");
}
- cmd_obj_sp = GetCommandSPExact("frame variable", false);
+ cmd_obj_sp = GetCommandSPExact("frame variable");
if (cmd_obj_sp) {
AddAlias("v", cmd_obj_sp);
AddAlias("var", cmd_obj_sp);
AddAlias("vo", cmd_obj_sp, "--object-description");
}
- cmd_obj_sp = GetCommandSPExact("register", false);
+ cmd_obj_sp = GetCommandSPExact("register");
if (cmd_obj_sp) {
AddAlias("re", cmd_obj_sp);
}
+
+ cmd_obj_sp = GetCommandSPExact("session history");
+ if (cmd_obj_sp) {
+ AddAlias("history", cmd_obj_sp);
+ }
}
void CommandInterpreter::Clear() {
@@ -460,54 +482,40 @@ const char *CommandInterpreter::ProcessEmbeddedScriptCommands(const char *arg) {
return arg;
}
+#define REGISTER_COMMAND_OBJECT(NAME, CLASS) \
+ m_command_dict[NAME] = std::make_shared<CLASS>(*this);
+
void CommandInterpreter::LoadCommandDictionary() {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
-
- lldb::ScriptLanguage script_language = m_debugger.GetScriptLanguage();
-
- m_command_dict["apropos"] = CommandObjectSP(new CommandObjectApropos(*this));
- m_command_dict["breakpoint"] =
- CommandObjectSP(new CommandObjectMultiwordBreakpoint(*this));
- m_command_dict["command"] =
- CommandObjectSP(new CommandObjectMultiwordCommands(*this));
- m_command_dict["disassemble"] =
- CommandObjectSP(new CommandObjectDisassemble(*this));
- m_command_dict["expression"] =
- CommandObjectSP(new CommandObjectExpression(*this));
- m_command_dict["frame"] =
- CommandObjectSP(new CommandObjectMultiwordFrame(*this));
- m_command_dict["gui"] = CommandObjectSP(new CommandObjectGUI(*this));
- m_command_dict["help"] = CommandObjectSP(new CommandObjectHelp(*this));
- m_command_dict["log"] = CommandObjectSP(new CommandObjectLog(*this));
- m_command_dict["memory"] = CommandObjectSP(new CommandObjectMemory(*this));
- m_command_dict["platform"] =
- CommandObjectSP(new CommandObjectPlatform(*this));
- m_command_dict["plugin"] = CommandObjectSP(new CommandObjectPlugin(*this));
- m_command_dict["process"] =
- CommandObjectSP(new CommandObjectMultiwordProcess(*this));
- m_command_dict["quit"] = CommandObjectSP(new CommandObjectQuit(*this));
- m_command_dict["register"] =
- CommandObjectSP(new CommandObjectRegister(*this));
- m_command_dict["reproducer"] =
- CommandObjectSP(new CommandObjectReproducer(*this));
- m_command_dict["script"] =
- CommandObjectSP(new CommandObjectScript(*this, script_language));
- m_command_dict["settings"] =
- CommandObjectSP(new CommandObjectMultiwordSettings(*this));
- m_command_dict["source"] =
- CommandObjectSP(new CommandObjectMultiwordSource(*this));
- m_command_dict["statistics"] = CommandObjectSP(new CommandObjectStats(*this));
- m_command_dict["target"] =
- CommandObjectSP(new CommandObjectMultiwordTarget(*this));
- m_command_dict["thread"] =
- CommandObjectSP(new CommandObjectMultiwordThread(*this));
- m_command_dict["type"] = CommandObjectSP(new CommandObjectType(*this));
- m_command_dict["version"] = CommandObjectSP(new CommandObjectVersion(*this));
- m_command_dict["watchpoint"] =
- CommandObjectSP(new CommandObjectMultiwordWatchpoint(*this));
- m_command_dict["language"] =
- CommandObjectSP(new CommandObjectLanguage(*this));
+ LLDB_SCOPED_TIMER();
+
+ REGISTER_COMMAND_OBJECT("apropos", CommandObjectApropos);
+ REGISTER_COMMAND_OBJECT("breakpoint", CommandObjectMultiwordBreakpoint);
+ REGISTER_COMMAND_OBJECT("command", CommandObjectMultiwordCommands);
+ REGISTER_COMMAND_OBJECT("disassemble", CommandObjectDisassemble);
+ REGISTER_COMMAND_OBJECT("expression", CommandObjectExpression);
+ REGISTER_COMMAND_OBJECT("frame", CommandObjectMultiwordFrame);
+ REGISTER_COMMAND_OBJECT("gui", CommandObjectGUI);
+ REGISTER_COMMAND_OBJECT("help", CommandObjectHelp);
+ REGISTER_COMMAND_OBJECT("log", CommandObjectLog);
+ REGISTER_COMMAND_OBJECT("memory", CommandObjectMemory);
+ REGISTER_COMMAND_OBJECT("platform", CommandObjectPlatform);
+ REGISTER_COMMAND_OBJECT("plugin", CommandObjectPlugin);
+ REGISTER_COMMAND_OBJECT("process", CommandObjectMultiwordProcess);
+ REGISTER_COMMAND_OBJECT("quit", CommandObjectQuit);
+ REGISTER_COMMAND_OBJECT("register", CommandObjectRegister);
+ REGISTER_COMMAND_OBJECT("reproducer", CommandObjectReproducer);
+ REGISTER_COMMAND_OBJECT("script", CommandObjectScript);
+ REGISTER_COMMAND_OBJECT("settings", CommandObjectMultiwordSettings);
+ REGISTER_COMMAND_OBJECT("session", CommandObjectSession);
+ REGISTER_COMMAND_OBJECT("source", CommandObjectMultiwordSource);
+ REGISTER_COMMAND_OBJECT("statistics", CommandObjectStats);
+ REGISTER_COMMAND_OBJECT("target", CommandObjectMultiwordTarget);
+ REGISTER_COMMAND_OBJECT("thread", CommandObjectMultiwordThread);
+ REGISTER_COMMAND_OBJECT("trace", CommandObjectTrace);
+ REGISTER_COMMAND_OBJECT("type", CommandObjectType);
+ REGISTER_COMMAND_OBJECT("version", CommandObjectVersion);
+ REGISTER_COMMAND_OBJECT("watchpoint", CommandObjectMultiwordWatchpoint);
+ REGISTER_COMMAND_OBJECT("language", CommandObjectLanguage);
// clang-format off
const char *break_regexes[][2] = {
@@ -624,15 +632,10 @@ void CommandInterpreter::LoadCommandDictionary() {
if (tbreak_regex_cmd_up) {
bool success = true;
for (size_t i = 0; i < num_regexes; i++) {
- // If you add a resultant command string longer than 1024 characters be
- // sure to increase the size of this buffer.
- char buffer[1024];
- int num_printed =
- snprintf(buffer, 1024, "%s %s", break_regexes[i][1], "-o 1");
- lldbassert(num_printed < 1024);
- UNUSED_IF_ASSERT_DISABLED(num_printed);
+ std::string command = break_regexes[i][1];
+ command += " -o 1";
success =
- tbreak_regex_cmd_up->AddRegexCommand(break_regexes[i][0], buffer);
+ tbreak_regex_cmd_up->AddRegexCommand(break_regexes[i][0], command);
if (!success)
break;
}
@@ -1034,47 +1037,46 @@ bool CommandInterpreter::AddUserCommand(llvm::StringRef name,
return false;
}
-CommandObjectSP CommandInterpreter::GetCommandSPExact(llvm::StringRef cmd_str,
- bool include_aliases) const {
- Args cmd_words(cmd_str); // Break up the command string into words, in case
- // it's a multi-word command.
- CommandObjectSP ret_val; // Possibly empty return value.
+CommandObjectSP
+CommandInterpreter::GetCommandSPExact(llvm::StringRef cmd_str,
+ bool include_aliases) const {
+ // Break up the command string into words, in case it's a multi-word command.
+ Args cmd_words(cmd_str);
if (cmd_str.empty())
- return ret_val;
+ return {};
if (cmd_words.GetArgumentCount() == 1)
- return GetCommandSP(cmd_str, include_aliases, true, nullptr);
- else {
- // We have a multi-word command (seemingly), so we need to do more work.
- // First, get the cmd_obj_sp for the first word in the command.
- CommandObjectSP cmd_obj_sp = GetCommandSP(llvm::StringRef(cmd_words.GetArgumentAtIndex(0)),
- include_aliases, true, nullptr);
- if (cmd_obj_sp.get() != nullptr) {
- // Loop through the rest of the words in the command (everything passed
- // in was supposed to be part of a command name), and find the
- // appropriate sub-command SP for each command word....
- size_t end = cmd_words.GetArgumentCount();
- for (size_t j = 1; j < end; ++j) {
- if (cmd_obj_sp->IsMultiwordObject()) {
- cmd_obj_sp =
- cmd_obj_sp->GetSubcommandSP(cmd_words.GetArgumentAtIndex(j));
- if (cmd_obj_sp.get() == nullptr)
- // The sub-command name was invalid. Fail and return the empty
- // 'ret_val'.
- return ret_val;
- } else
- // We have more words in the command name, but we don't have a
- // multiword object. Fail and return empty 'ret_val'.
- return ret_val;
- }
- // We successfully looped through all the command words and got valid
- // command objects for them. Assign the last object retrieved to
- // 'ret_val'.
- ret_val = cmd_obj_sp;
+ return GetCommandSP(cmd_str, include_aliases, true);
+
+ // We have a multi-word command (seemingly), so we need to do more work.
+ // First, get the cmd_obj_sp for the first word in the command.
+ CommandObjectSP cmd_obj_sp =
+ GetCommandSP(cmd_words.GetArgumentAtIndex(0), include_aliases, true);
+ if (!cmd_obj_sp)
+ return {};
+
+ // Loop through the rest of the words in the command (everything passed in
+ // was supposed to be part of a command name), and find the appropriate
+ // sub-command SP for each command word....
+ size_t end = cmd_words.GetArgumentCount();
+ for (size_t i = 1; i < end; ++i) {
+ if (!cmd_obj_sp->IsMultiwordObject()) {
+ // We have more words in the command name, but we don't have a
+ // multiword object. Fail and return.
+ return {};
+ }
+
+ cmd_obj_sp = cmd_obj_sp->GetSubcommandSP(cmd_words.GetArgumentAtIndex(i));
+ if (!cmd_obj_sp) {
+ // The sub-command name was invalid. Fail and return.
+ return {};
}
}
- return ret_val;
+
+ // We successfully looped through all the command words and got valid
+ // command objects for them.
+ return cmd_obj_sp;
}
CommandObject *
@@ -1518,16 +1520,12 @@ Status CommandInterpreter::PreprocessCommand(std::string &command) {
end_backtick - expr_content_start);
ExecutionContext exe_ctx(GetExecutionContext());
- Target *target = exe_ctx.GetTargetPtr();
// Get a dummy target to allow for calculator mode while processing
// backticks. This also helps break the infinite loop caused when target is
// null.
- if (!target)
- target = m_debugger.GetDummyTarget();
-
- if (!target)
- continue;
+ Target *exe_target = exe_ctx.GetTargetPtr();
+ Target &target = exe_target ? *exe_target : m_debugger.GetDummyTarget();
ValueObjectSP expr_result_valobj_sp;
@@ -1540,8 +1538,8 @@ Status CommandInterpreter::PreprocessCommand(std::string &command) {
options.SetTimeout(llvm::None);
ExpressionResults expr_result =
- target->EvaluateExpression(expr_str.c_str(), exe_ctx.GetFramePtr(),
- expr_result_valobj_sp, options);
+ target.EvaluateExpression(expr_str.c_str(), exe_ctx.GetFramePtr(),
+ expr_result_valobj_sp, options);
if (expr_result == eExpressionCompleted) {
Scalar scalar;
@@ -1648,9 +1646,7 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
command_line);
LLDB_LOGF(log, "Processing command: %s", command_line);
-
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "Handling command: %s.", command_line);
+ LLDB_SCOPED_TIMERF("Processing command: %s.", command_line);
if (!no_context_switching)
UpdateExecutionContext(override_context);
@@ -1667,6 +1663,8 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
else
add_to_history = (lazy_add_to_history == eLazyBoolYes);
+ m_transcript_stream << "(lldb) " << command_line << '\n';
+
bool empty_command = false;
bool comment_command = false;
if (command_string.empty())
@@ -1708,7 +1706,7 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
command_string = command_line;
original_command_string = command_line;
if (m_repeat_command.empty()) {
- result.AppendErrorWithFormat("No auto repeat.\n");
+ result.AppendError("No auto repeat.");
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -1799,6 +1797,9 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
LLDB_LOGF(log, "HandleCommand, command %s",
(result.Succeeded() ? "succeeded" : "did not succeed"));
+ m_transcript_stream << result.GetOutputData();
+ m_transcript_stream << result.GetErrorData();
+
return result.Succeeded();
}
@@ -1871,6 +1872,19 @@ void CommandInterpreter::HandleCompletion(CompletionRequest &request) {
HandleCompletionMatches(request);
}
+llvm::Optional<std::string>
+CommandInterpreter::GetAutoSuggestionForCommand(llvm::StringRef line) {
+ if (line.empty())
+ return llvm::None;
+ const size_t s = m_command_history.GetSize();
+ for (int i = s - 1; i >= 0; --i) {
+ llvm::StringRef entry = m_command_history.GetStringAtIndex(i);
+ if (entry.consume_front(line))
+ return entry.str();
+ }
+ return llvm::None;
+}
+
CommandInterpreter::~CommandInterpreter() {}
void CommandInterpreter::UpdatePrompt(llvm::StringRef new_prompt) {
@@ -1975,10 +1989,7 @@ void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj,
if (value_type != OptionParser::eOptionalArgument)
new_args.AppendArgument(value);
else {
- char buffer[255];
- ::snprintf(buffer, sizeof(buffer), "%s%s", option.c_str(),
- value.c_str());
- new_args.AppendArgument(llvm::StringRef(buffer));
+ new_args.AppendArgument(option + value);
}
} else if (static_cast<size_t>(index) >= cmd_args.GetArgumentCount()) {
@@ -2000,10 +2011,7 @@ void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj,
if (value_type != OptionParser::eOptionalArgument)
new_args.AppendArgument(cmd_args.GetArgumentAtIndex(index));
else {
- char buffer[255];
- ::snprintf(buffer, sizeof(buffer), "%s%s", option.c_str(),
- cmd_args.GetArgumentAtIndex(index));
- new_args.AppendArgument(buffer);
+ new_args.AppendArgument(option + cmd_args.GetArgumentAtIndex(index));
}
used[index] = true;
}
@@ -2070,12 +2078,30 @@ static void GetHomeInitFile(llvm::SmallVectorImpl<char> &init_file,
init_file_name.append(suffix.str());
}
- llvm::sys::path::home_directory(init_file);
+ FileSystem::Instance().GetHomeDirectory(init_file);
llvm::sys::path::append(init_file, init_file_name);
FileSystem::Instance().Resolve(init_file);
}
+static void GetHomeREPLInitFile(llvm::SmallVectorImpl<char> &init_file) {
+ LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs();
+ LanguageType language = eLanguageTypeUnknown;
+ if (auto main_repl_language = repl_languages.GetSingularLanguage())
+ language = *main_repl_language;
+ else
+ return;
+
+ std::string init_file_name =
+ (llvm::Twine(".lldbinit-") +
+ llvm::Twine(Language::GetNameForLanguageType(language)) +
+ llvm::Twine("-repl"))
+ .str();
+ FileSystem::Instance().GetHomeDirectory(init_file);
+ llvm::sys::path::append(init_file, init_file_name);
+ FileSystem::Instance().Resolve(init_file);
+}
+
static void GetCwdInitFile(llvm::SmallVectorImpl<char> &init_file) {
llvm::StringRef s = ".lldbinit";
init_file.assign(s.begin(), s.end());
@@ -2141,7 +2167,7 @@ void CommandInterpreter::SourceInitFileCwd(CommandReturnObject &result) {
llvm::sys::path::parent_path(home_init_file)) {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else {
- result.AppendErrorWithFormat(InitFileWarning);
+ result.AppendError(InitFileWarning);
result.SetStatus(eReturnStatusFailed);
}
}
@@ -2150,15 +2176,22 @@ void CommandInterpreter::SourceInitFileCwd(CommandReturnObject &result) {
/// We will first see if there is an application specific ".lldbinit" file
/// whose name is "~/.lldbinit" followed by a "-" and the name of the program.
-/// If this file doesn't exist, we fall back to just the "~/.lldbinit" file.
-void CommandInterpreter::SourceInitFileHome(CommandReturnObject &result) {
+/// If this file doesn't exist, we fall back to the REPL init file or the
+/// default home init file in "~/.lldbinit".
+void CommandInterpreter::SourceInitFileHome(CommandReturnObject &result,
+ bool is_repl) {
if (m_skip_lldbinit_files) {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
return;
}
llvm::SmallString<128> init_file;
- GetHomeInitFile(init_file);
+
+ if (is_repl)
+ GetHomeREPLInitFile(init_file);
+
+ if (init_file.empty())
+ GetHomeInitFile(init_file);
if (!m_skip_app_init_files) {
llvm::StringRef program_name =
@@ -2265,6 +2298,8 @@ void CommandInterpreter::HandleCommands(const StringList &commands,
}
CommandReturnObject tmp_result(m_debugger.GetUseColor());
+ tmp_result.SetInteractive(result.GetInteractive());
+
// If override_context is not NULL, pass no_context_switching = true for
// HandleCommand() since we updated our context already.
@@ -2512,11 +2547,15 @@ void CommandInterpreter::HandleCommandsFromFile(
debugger.SetAsyncExecution(false);
m_command_source_depth++;
+ m_command_source_dirs.push_back(cmd_file.CopyByRemovingLastPathComponent());
debugger.RunIOHandlerSync(io_handler_sp);
if (!m_command_source_flags.empty())
m_command_source_flags.pop_back();
+
+ m_command_source_dirs.pop_back();
m_command_source_depth--;
+
result.SetStatus(eReturnStatusSuccessFinishNoResult);
debugger.SetAsyncExecution(old_async_execution);
}
@@ -2877,6 +2916,57 @@ bool CommandInterpreter::IOHandlerInterrupt(IOHandler &io_handler) {
return false;
}
+bool CommandInterpreter::SaveTranscript(
+ CommandReturnObject &result, llvm::Optional<std::string> output_file) {
+ if (output_file == llvm::None || output_file->empty()) {
+ std::string now = llvm::to_string(std::chrono::system_clock::now());
+ std::replace(now.begin(), now.end(), ' ', '_');
+ const std::string file_name = "lldb_session_" + now + ".log";
+ FileSpec tmp = HostInfo::GetGlobalTempDir();
+ tmp.AppendPathComponent(file_name);
+ output_file = tmp.GetPath();
+ }
+
+ auto error_out = [&](llvm::StringRef error_message, std::string description) {
+ LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMANDS), "{0} ({1}:{2})",
+ error_message, output_file, description);
+ result.AppendErrorWithFormatv(
+ "Failed to save session's transcripts to {0}!", *output_file);
+ return false;
+ };
+
+ File::OpenOptions flags = File::eOpenOptionWrite |
+ File::eOpenOptionCanCreate |
+ File::eOpenOptionTruncate;
+
+ auto opened_file = FileSystem::Instance().Open(FileSpec(*output_file), flags);
+
+ if (!opened_file)
+ return error_out("Unable to create file",
+ llvm::toString(opened_file.takeError()));
+
+ FileUP file = std::move(opened_file.get());
+
+ size_t byte_size = m_transcript_stream.GetSize();
+
+ Status error = file->Write(m_transcript_stream.GetData(), byte_size);
+
+ if (error.Fail() || byte_size != m_transcript_stream.GetSize())
+ return error_out("Unable to write to destination file",
+ "Bytes written do not match transcript size.");
+
+ result.AppendMessageWithFormat("Session's transcripts saved to %s\n",
+ output_file->c_str());
+
+ return true;
+}
+
+FileSpec CommandInterpreter::GetCurrentSourceDir() {
+ if (m_command_source_dirs.empty())
+ return {};
+ return m_command_source_dirs.back();
+}
+
void CommandInterpreter::GetLLDBCommandsFromIOHandler(
const char *prompt, IOHandlerDelegate &delegate, void *baton) {
Debugger &debugger = GetDebugger();
diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp
index 538f7a1ba693..71adf8c39f1b 100644
--- a/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp
+++ b/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp
@@ -258,6 +258,15 @@ bool CommandObject::CheckRequirements(CommandReturnObject &result) {
}
}
}
+
+ if (GetFlags().Test(eCommandProcessMustBeTraced)) {
+ Target *target = m_exe_ctx.GetTargetPtr();
+ if (target && !target->GetTrace()) {
+ result.SetError("Process is not being traced.");
+ return false;
+ }
+ }
+
return true;
}
@@ -930,11 +939,11 @@ const char *CommandObject::GetArgumentDescriptionAsCString(
}
Target &CommandObject::GetDummyTarget() {
- return *m_interpreter.GetDebugger().GetDummyTarget();
+ return m_interpreter.GetDebugger().GetDummyTarget();
}
Target &CommandObject::GetSelectedOrDummyTarget(bool prefer_dummy) {
- return *m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy);
+ return m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy);
}
Target &CommandObject::GetSelectedTarget() {
@@ -1041,13 +1050,13 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = {
{ eArgTypeBoolean, "boolean", CommandCompletions::eNoCompletion, { nullptr, false }, "A Boolean value: 'true' or 'false'" },
{ eArgTypeBreakpointID, "breakpt-id", CommandCompletions::eNoCompletion, { BreakpointIDHelpTextCallback, false }, nullptr },
{ eArgTypeBreakpointIDRange, "breakpt-id-list", CommandCompletions::eNoCompletion, { BreakpointIDRangeHelpTextCallback, false }, nullptr },
- { eArgTypeBreakpointName, "breakpoint-name", CommandCompletions::eNoCompletion, { BreakpointNameHelpTextCallback, false }, nullptr },
+ { eArgTypeBreakpointName, "breakpoint-name", CommandCompletions::eBreakpointNameCompletion, { BreakpointNameHelpTextCallback, false }, nullptr },
{ eArgTypeByteSize, "byte-size", CommandCompletions::eNoCompletion, { nullptr, false }, "Number of bytes to use." },
{ eArgTypeClassName, "class-name", CommandCompletions::eNoCompletion, { nullptr, false }, "Then name of a class from the debug information in the program." },
{ eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, { nullptr, false }, "A debugger command (may be multiple words), without any options or arguments." },
{ eArgTypeCount, "count", CommandCompletions::eNoCompletion, { nullptr, false }, "An unsigned integer." },
{ eArgTypeDirectoryName, "directory", CommandCompletions::eDiskDirectoryCompletion, { nullptr, false }, "A directory name." },
- { eArgTypeDisassemblyFlavor, "disassembly-flavor", CommandCompletions::eNoCompletion, { nullptr, false }, "A disassembly flavor recognized by your disassembly plugin. Currently the only valid options are \"att\" and \"intel\" for Intel targets" },
+ { eArgTypeDisassemblyFlavor, "disassembly-flavor", CommandCompletions::eDisassemblyFlavorCompletion, { nullptr, false }, "A disassembly flavor recognized by your disassembly plugin. Currently the only valid options are \"att\" and \"intel\" for Intel targets" },
{ eArgTypeDescriptionVerbosity, "description-verbosity", CommandCompletions::eNoCompletion, { nullptr, false }, "How verbose the output of 'po' should be." },
{ eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
{ eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
@@ -1055,19 +1064,20 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = {
{ eArgTypeExprFormat, "expression-format", CommandCompletions::eNoCompletion, { nullptr, false }, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]" },
{ eArgTypeFilename, "filename", CommandCompletions::eDiskFileCompletion, { nullptr, false }, "The name of a file (can include path)." },
{ eArgTypeFormat, "format", CommandCompletions::eNoCompletion, { FormatHelpTextCallback, true }, nullptr },
- { eArgTypeFrameIndex, "frame-index", CommandCompletions::eNoCompletion, { nullptr, false }, "Index into a thread's list of frames." },
+ { eArgTypeFrameIndex, "frame-index", CommandCompletions::eFrameIndexCompletion, { nullptr, false }, "Index into a thread's list of frames." },
{ eArgTypeFullName, "fullname", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
{ eArgTypeFunctionName, "function-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a function." },
{ eArgTypeFunctionOrSymbol, "function-or-symbol", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a function or symbol." },
{ 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, "source-language", CommandCompletions::eNoCompletion, { LanguageTypeHelpTextCallback, true }, nullptr },
+ { eArgTypeLanguage, "source-language", CommandCompletions::eTypeLanguageCompletion, { LanguageTypeHelpTextCallback, true }, nullptr },
{ eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, { nullptr, false }, "Line number in a source file." },
+ { eArgTypeFileLineColumn, "linespec", CommandCompletions::eNoCompletion, { nullptr, false }, "A source specifier in the form file:line[:column]" },
{ 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)." },
{ eArgTypeMethod, "method", CommandCompletions::eNoCompletion, { nullptr, false }, "A C++ method name." },
- { eArgTypeName, "name", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
+ { eArgTypeName, "name", CommandCompletions::eTypeCategoryNameCompletion, { nullptr, false }, "Help text goes here." },
{ eArgTypeNewPathPrefix, "new-path-prefix", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
{ eArgTypeNumLines, "num-lines", CommandCompletions::eNoCompletion, { nullptr, false }, "The number of lines to use." },
{ eArgTypeNumberPerLine, "number-per-line", CommandCompletions::eNoCompletion, { nullptr, false }, "The number of items per line to display." },
@@ -1077,9 +1087,9 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = {
{ eArgTypePath, "path", CommandCompletions::eDiskFileCompletion, { nullptr, false }, "Path." },
{ eArgTypePermissionsNumber, "perms-numeric", CommandCompletions::eNoCompletion, { nullptr, false }, "Permissions given as an octal number (e.g. 755)." },
{ eArgTypePermissionsString, "perms=string", CommandCompletions::eNoCompletion, { nullptr, false }, "Permissions given as a string value (e.g. rw-r-xr--)." },
- { eArgTypePid, "pid", CommandCompletions::eNoCompletion, { nullptr, false }, "The process ID number." },
+ { eArgTypePid, "pid", CommandCompletions::eProcessIDCompletion, { nullptr, false }, "The process ID number." },
{ eArgTypePlugin, "plugin", CommandCompletions::eProcessPluginCompletion, { nullptr, false }, "Help text goes here." },
- { eArgTypeProcessName, "process-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of the process." },
+ { eArgTypeProcessName, "process-name", CommandCompletions::eProcessNameCompletion, { nullptr, false }, "The name of the process." },
{ eArgTypePythonClass, "python-class", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a Python class." },
{ eArgTypePythonFunction, "python-function", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a Python function." },
{ eArgTypePythonScript, "python-script", CommandCompletions::eNoCompletion, { nullptr, false }, "Source code written in Python." },
@@ -1118,7 +1128,8 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = {
{ 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." },
{ eArgTypeCommand, "command", CommandCompletions::eNoCompletion, { nullptr, false }, "An LLDB Command line command." },
- { eArgTypeColumnNum, "column", CommandCompletions::eNoCompletion, { nullptr, false }, "Column number in a source file." }
+ { eArgTypeColumnNum, "column", CommandCompletions::eNoCompletion, { nullptr, false }, "Column number in a source file." },
+ { eArgTypeModuleUUID, "module-uuid", CommandCompletions::eModuleUUIDCompletion, { nullptr, false }, "A module UUID value." }
// clang-format on
};
diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandObjectScript.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandObjectScript.cpp
deleted file mode 100644
index 5e98c658ebdb..000000000000
--- a/contrib/llvm-project/lldb/source/Interpreter/CommandObjectScript.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-//===-- CommandObjectScript.cpp -------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "CommandObjectScript.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/DataFormatters/DataVisualization.h"
-#include "lldb/Host/Config.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/ScriptInterpreter.h"
-#include "lldb/Utility/Args.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-// CommandObjectScript
-
-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>]") {}
-
-CommandObjectScript::~CommandObjectScript() {}
-
-bool CommandObjectScript::DoExecute(llvm::StringRef command,
- CommandReturnObject &result) {
- if (m_interpreter.GetDebugger().GetScriptLanguage() ==
- lldb::eScriptLanguageNone) {
- result.AppendError(
- "the script-lang setting is set to none - scripting not available");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- ScriptInterpreter *script_interpreter = GetDebugger().GetScriptInterpreter();
-
- if (script_interpreter == nullptr) {
- result.AppendError("no script interpreter");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- // Script might change Python code we use for formatting. Make sure we keep
- // up to date with it.
- DataVisualization::ForceUpdate();
-
- if (command.empty()) {
- script_interpreter->ExecuteInterpreterLoop();
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return result.Succeeded();
- }
-
- // We can do better when reporting the status of one-liner script execution.
- if (script_interpreter->ExecuteOneLine(command, &result))
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- else
- result.SetStatus(eReturnStatusFailed);
-
- return result.Succeeded();
-}
diff --git a/contrib/llvm-project/lldb/source/Interpreter/InterpreterProperties.td b/contrib/llvm-project/lldb/source/Interpreter/InterpreterProperties.td
index 600c1e3edb9b..e5346d14a6e1 100644
--- a/contrib/llvm-project/lldb/source/Interpreter/InterpreterProperties.td
+++ b/contrib/llvm-project/lldb/source/Interpreter/InterpreterProperties.td
@@ -9,6 +9,10 @@ let Definition = "interpreter" in {
Global,
DefaultTrue,
Desc<"If true, LLDB will prompt you before quitting if there are any live processes being debugged. If false, LLDB will quit without asking in any case.">;
+ def SaveSessionOnQuit: Property<"save-session-on-quit", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"If true, LLDB will save the session's transcripts before quitting.">;
def StopCmdSourceOnError: Property<"stop-command-source-on-error", "Boolean">,
Global,
DefaultTrue,
diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupUUID.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupUUID.cpp
index 46f2ff75225a..dc6f4139896f 100644
--- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupUUID.cpp
+++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupUUID.cpp
@@ -19,7 +19,7 @@ OptionGroupUUID::~OptionGroupUUID() {}
static constexpr OptionDefinition g_option_table[] = {
{LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eRequiredArgument,
- nullptr, {}, 0, eArgTypeNone, "A module UUID value."},
+ nullptr, {}, 0, eArgTypeModuleUUID, "A module UUID value."},
};
llvm::ArrayRef<OptionDefinition> OptionGroupUUID::GetDefinitions() {
diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValue.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValue.cpp
index 198be85a7b47..0bd9a591af67 100644
--- a/contrib/llvm-project/lldb/source/Interpreter/OptionValue.cpp
+++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValue.cpp
@@ -39,7 +39,7 @@ Status OptionValue::SetSubValue(const ExecutionContext *exe_ctx,
VarSetOperationType op, llvm::StringRef name,
llvm::StringRef value) {
Status error;
- error.SetErrorStringWithFormat("SetSubValue is not supported");
+ error.SetErrorString("SetSubValue is not supported");
return error;
}
@@ -471,6 +471,8 @@ const char *OptionValue::GetBuiltinTypeAsCString(Type t) {
return "dictionary";
case eTypeEnum:
return "enum";
+ case eTypeFileLineColumn:
+ return "file:line:column specifier";
case eTypeFileSpec:
return "file";
case eTypeFileSpecList:
diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp
index 9be11e32e2db..0b293ccfc248 100644
--- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp
+++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp
@@ -52,6 +52,7 @@ void OptionValueArray::DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
case eTypeChar:
case eTypeEnum:
case eTypeFileSpec:
+ case eTypeFileLineColumn:
case eTypeFormat:
case eTypeSInt64:
case eTypeString:
diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp
index caadccd04232..79323f502d17 100644
--- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp
+++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp
@@ -62,6 +62,7 @@ void OptionValueDictionary::DumpValue(const ExecutionContext *exe_ctx,
case eTypeBoolean:
case eTypeChar:
case eTypeEnum:
+ case eTypeFileLineColumn:
case eTypeFileSpec:
case eTypeFormat:
case eTypeSInt64:
diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileColonLine.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileColonLine.cpp
new file mode 100644
index 000000000000..dac557c4248a
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileColonLine.cpp
@@ -0,0 +1,145 @@
+//===-- OptionValueFileColonLine.cpp---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueFileColonLine.h"
+
+#include "lldb/DataFormatters/FormatManager.h"
+#include "lldb/Interpreter/CommandCompletions.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Utility/Args.h"
+#include "lldb/Utility/State.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+// This is an OptionValue for parsing file:line:column specifications.
+// I set the completer to "source file" which isn't quite right, but we can
+// only usefully complete in the file name part of it so it should be good
+// enough.
+OptionValueFileColonLine::OptionValueFileColonLine()
+ : OptionValue(), m_file_spec(), m_line_number(LLDB_INVALID_LINE_NUMBER),
+ m_column_number(LLDB_INVALID_COLUMN_NUMBER),
+ m_completion_mask(CommandCompletions::eSourceFileCompletion) {}
+
+OptionValueFileColonLine::OptionValueFileColonLine(llvm::StringRef input)
+ : OptionValue(), m_file_spec(), m_line_number(LLDB_INVALID_LINE_NUMBER),
+ m_column_number(LLDB_INVALID_COLUMN_NUMBER),
+ m_completion_mask(CommandCompletions::eSourceFileCompletion) {
+ SetValueFromString(input, eVarSetOperationAssign);
+}
+
+void OptionValueFileColonLine::DumpValue(const ExecutionContext *exe_ctx,
+ Stream &strm, uint32_t dump_mask) {
+ if (dump_mask & eDumpOptionType)
+ strm.Printf("(%s)", GetTypeAsCString());
+ if (dump_mask & eDumpOptionValue) {
+ if (dump_mask & eDumpOptionType)
+ strm.PutCString(" = ");
+
+ if (m_file_spec)
+ strm << '"' << m_file_spec.GetPath().c_str() << '"';
+ if (m_line_number != LLDB_INVALID_LINE_NUMBER)
+ strm.Printf(":%d", m_line_number);
+ if (m_column_number != LLDB_INVALID_COLUMN_NUMBER)
+ strm.Printf(":%d", m_column_number);
+ }
+}
+
+Status OptionValueFileColonLine::SetValueFromString(llvm::StringRef value,
+ VarSetOperationType op) {
+ Status error;
+ switch (op) {
+ case eVarSetOperationClear:
+ Clear();
+ NotifyValueChanged();
+ break;
+
+ case eVarSetOperationReplace:
+ case eVarSetOperationAssign:
+ if (value.size() > 0) {
+ // This is in the form filename:linenumber:column.
+ // I wish we could use filename:linenumber.column, that would make the
+ // parsing unambiguous and so much easier...
+ // But clang & gcc both print the output with two : so we're stuck with
+ // the two colons. Practically, the only actual ambiguity this introduces
+ // is with files like "foo:10", which doesn't seem terribly likely.
+
+ // Providing the column is optional, so the input value might have one or
+ // two colons. First pick off the last colon separated piece.
+ // It has to be there, since the line number is required:
+ llvm::StringRef last_piece;
+ llvm::StringRef left_of_last_piece;
+
+ std::tie(left_of_last_piece, last_piece) = value.rsplit(':');
+ if (last_piece.empty()) {
+ error.SetErrorStringWithFormat("Line specifier must include file and "
+ "line: '%s'",
+ value.str().c_str());
+ return error;
+ }
+
+ // Now see if there's another colon and if so pull out the middle piece:
+ // Then check whether the middle piece is an integer. If it is, then it
+ // was the line number, and if it isn't we're going to assume that there
+ // was a colon in the filename (see note at the beginning of the function)
+ // and ignore it.
+ llvm::StringRef file_name;
+ llvm::StringRef middle_piece;
+
+ std::tie(file_name, middle_piece) = left_of_last_piece.rsplit(':');
+ if (middle_piece.empty() || !llvm::to_integer(middle_piece,
+ m_line_number)) {
+ // The middle piece was empty or not an integer, so there were only two
+ // legit pieces; our original division was right. Reassign the file
+ // name and pull out the line number:
+ file_name = left_of_last_piece;
+ if (!llvm::to_integer(last_piece, m_line_number)) {
+ error.SetErrorStringWithFormat("Bad line number value '%s' in: '%s'",
+ last_piece.str().c_str(),
+ value.str().c_str());
+ return error;
+ }
+ } else {
+ // There were three pieces, and we've got the line number. So now
+ // we just need to check the column number which was the last peice.
+ if (!llvm::to_integer(last_piece, m_column_number)) {
+ error.SetErrorStringWithFormat("Bad column value '%s' in: '%s'",
+ last_piece.str().c_str(),
+ value.str().c_str());
+ return error;
+ }
+ }
+
+ m_value_was_set = true;
+ m_file_spec.SetFile(file_name, FileSpec::Style::native);
+ NotifyValueChanged();
+ } else {
+ error.SetErrorString("invalid value string");
+ }
+ break;
+
+ case eVarSetOperationInsertBefore:
+ case eVarSetOperationInsertAfter:
+ case eVarSetOperationRemove:
+ case eVarSetOperationAppend:
+ case eVarSetOperationInvalid:
+ error = OptionValue::SetValueFromString(value, op);
+ break;
+ }
+ return error;
+}
+
+lldb::OptionValueSP OptionValueFileColonLine::DeepCopy() const {
+ return OptionValueSP(new OptionValueFileColonLine(*this));
+}
+
+void OptionValueFileColonLine::AutoComplete(CommandInterpreter &interpreter,
+ CompletionRequest &request) {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ interpreter, m_completion_mask, request, nullptr);
+}
diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp
index 15acb7e5e5b0..a03fd55d0385 100644
--- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp
+++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp
@@ -64,13 +64,6 @@ Status OptionValueFileSpec::SetValueFromString(llvm::StringRef value,
case eVarSetOperationReplace:
case eVarSetOperationAssign:
if (value.size() > 0) {
- // The setting value may have whitespace, double-quotes, or single-quotes
- // around the file path to indicate that internal spaces are not word
- // breaks. Strip off any ws & quotes from the start and end of the file
- // path - we aren't doing any word // breaking here so the quoting is
- // unnecessary. NB this will cause a problem if someone tries to specify
- // a file path that legitimately begins or ends with a " or ' character,
- // or whitespace.
value = value.trim("\"' \t");
m_value_was_set = true;
m_current_value.SetFile(value.str(), FileSpec::Style::native);
diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFormatEntity.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFormatEntity.cpp
index 6b36bd575186..509a21752e48 100644
--- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFormatEntity.cpp
+++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFormatEntity.cpp
@@ -29,11 +29,10 @@ OptionValueFormatEntity::OptionValueFormatEntity(const char *default_format)
}
}
-bool OptionValueFormatEntity::Clear() {
+void OptionValueFormatEntity::Clear() {
m_current_entry = m_default_entry;
m_current_format = m_default_format;
m_value_was_set = false;
- return true;
}
static void EscapeBackticks(llvm::StringRef str, std::string &dst) {
@@ -85,7 +84,7 @@ Status OptionValueFormatEntity::SetValueFromString(llvm::StringRef value_str,
if (first_char == '"' || first_char == '\'') {
const size_t trimmed_len = trimmed_value_str.size();
if (trimmed_len == 1 || value_str[trimmed_len - 1] != first_char) {
- error.SetErrorStringWithFormat("mismatched quotes");
+ error.SetErrorString("mismatched quotes");
return error;
}
value_str = trimmed_value_str.substr(1, trimmed_len - 2);
diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp
index 24cda056977e..6c4e77f614f9 100644
--- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp
+++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp
@@ -147,38 +147,6 @@ OptionValueProperties::GetSubValue(const ExecutionContext *exe_ctx,
}
return return_val_sp;
}
- case '{':
- // Predicate matching for predicates like
- // "<setting-name>{<predicate>}"
- // strings are parsed by the current OptionValueProperties subclass to mean
- // whatever they want to. For instance a subclass of OptionValueProperties
- // for a lldb_private::Target might implement: "target.run-
- // args{arch==i386}" -- only set run args if the arch is i386 "target
- // .run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the path
- // matches "target.run-args{basename==test&&arch==x86_64}" -- only set run
- // args if executable basename is "test" and arch is "x86_64"
- if (sub_name[1]) {
- llvm::StringRef predicate_start = sub_name.drop_front();
- size_t pos = predicate_start.find('}');
- if (pos != llvm::StringRef::npos) {
- auto predicate = predicate_start.take_front(pos);
- auto rest = predicate_start.drop_front(pos);
- if (PredicateMatches(exe_ctx, predicate)) {
- if (!rest.empty()) {
- // Still more subvalue string to evaluate
- return value_sp->GetSubValue(exe_ctx, rest,
- will_modify, error);
- } else {
- // We have a match!
- break;
- }
- }
- }
- }
- // Predicate didn't match or wasn't correctly formed
- value_sp.reset();
- break;
-
case '[':
// Array or dictionary access for subvalues like: "[12]" -- access
// 12th array element "['hello']" -- dictionary access of key named hello
@@ -517,11 +485,10 @@ bool OptionValueProperties::SetPropertyAtIndexAsUInt64(
return false;
}
-bool OptionValueProperties::Clear() {
+void OptionValueProperties::Clear() {
const size_t num_properties = m_properties.size();
for (size_t i = 0; i < num_properties; ++i)
m_properties[i].GetValue()->Clear();
- return true;
}
Status OptionValueProperties::SetValueFromString(llvm::StringRef value,
diff --git a/contrib/llvm-project/lldb/source/Interpreter/Options.cpp b/contrib/llvm-project/lldb/source/Interpreter/Options.cpp
index c14b6b6ce66a..9ecc9e229e0e 100644
--- a/contrib/llvm-project/lldb/source/Interpreter/Options.cpp
+++ b/contrib/llvm-project/lldb/source/Interpreter/Options.cpp
@@ -223,7 +223,7 @@ Option *Options::GetLongOptions() {
std::map<int, uint32_t>::const_iterator pos =
option_seen.find(short_opt);
StreamString strm;
- if (isprint8(short_opt))
+ if (defs[i].HasShortOption())
Host::SystemLog(Host::eSystemLogError,
"option[%u] --%s has a short option -%c that "
"conflicts with option[%u] --%s, short option won't "
@@ -355,9 +355,7 @@ enum OptionDisplayType {
static bool PrintOption(const OptionDefinition &opt_def,
OptionDisplayType display_type, const char *header,
const char *footer, bool show_optional, Stream &strm) {
- const bool has_short_option = isprint8(opt_def.short_option) != 0;
-
- if (display_type == eDisplayShortOption && !has_short_option)
+ if (display_type == eDisplayShortOption && !opt_def.HasShortOption())
return false;
if (header && header[0])
@@ -366,7 +364,7 @@ static bool PrintOption(const OptionDefinition &opt_def,
if (show_optional && !opt_def.required)
strm.PutChar('[');
const bool show_short_option =
- has_short_option && display_type != eDisplayLongOption;
+ opt_def.HasShortOption() && display_type != eDisplayLongOption;
if (show_short_option)
strm.Printf("-%c", opt_def.short_option);
else
@@ -445,7 +443,7 @@ void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd,
std::set<int> options;
std::set<int>::const_iterator options_pos, options_end;
for (auto &def : opt_defs) {
- if (def.usage_mask & opt_set_mask && isprint8(def.short_option)) {
+ if (def.usage_mask & opt_set_mask && def.HasShortOption()) {
// Add current option to the end of out_stream.
if (def.required && def.option_has_arg == OptionParser::eNoArgument) {
@@ -470,7 +468,7 @@ void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd,
options.clear();
for (auto &def : opt_defs) {
- if (def.usage_mask & opt_set_mask && isprint8(def.short_option)) {
+ if (def.usage_mask & opt_set_mask && def.HasShortOption()) {
// Add current option to the end of out_stream.
if (!def.required &&
@@ -498,7 +496,7 @@ void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd,
// First go through and print the required options (list them up front).
for (auto &def : opt_defs) {
- if (def.usage_mask & opt_set_mask && isprint8(def.short_option)) {
+ if (def.usage_mask & opt_set_mask && def.HasShortOption()) {
if (def.required && def.option_has_arg != OptionParser::eNoArgument)
PrintOption(def, eDisplayBestOption, " ", nullptr, true, strm);
}
@@ -579,7 +577,7 @@ void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd,
arg_name_str.Printf("<%s>", CommandObject::GetArgumentName(arg_type));
strm.Indent();
- if (opt_defs[i].short_option && isprint8(opt_defs[i].short_option)) {
+ if (opt_defs[i].short_option && opt_defs[i].HasShortOption()) {
PrintOption(opt_defs[i], eDisplayShortOption, nullptr, nullptr, false,
strm);
PrintOption(opt_defs[i], eDisplayLongOption, " ( ", " )", false, strm);
@@ -1308,7 +1306,7 @@ llvm::Expected<Args> Options::Parse(const Args &args,
&long_options_index);
if (val == ':') {
- error.SetErrorStringWithFormat("last option requires an argument");
+ error.SetErrorString("last option requires an argument");
break;
}
@@ -1317,7 +1315,7 @@ llvm::Expected<Args> Options::Parse(const Args &args,
// Did we get an error?
if (val == '?') {
- error.SetErrorStringWithFormat("unknown or ambiguous option");
+ error.SetErrorString("unknown or ambiguous option");
break;
}
// The option auto-set itself
diff --git a/contrib/llvm-project/lldb/source/Interpreter/Property.cpp b/contrib/llvm-project/lldb/source/Interpreter/Property.cpp
index 923811249853..a02497662ff5 100644
--- a/contrib/llvm-project/lldb/source/Interpreter/Property.cpp
+++ b/contrib/llvm-project/lldb/source/Interpreter/Property.cpp
@@ -99,6 +99,12 @@ Property::Property(const PropertyDefinition &definition)
}
break;
+ case OptionValue::eTypeFileLineColumn:
+ // "definition.default_uint_value" is not used for a
+ // OptionValue::eTypeFileSpecList
+ m_value_sp = std::make_shared<OptionValueFileColonLine>();
+ break;
+
case OptionValue::eTypeFileSpec: {
// "definition.default_uint_value" represents if the
// "definition.default_cstr_value" should be resolved or not
diff --git a/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp b/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp
index 86620449f2f4..013ed6aecb80 100644
--- a/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp
+++ b/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -47,9 +47,11 @@ void ScriptInterpreter::CollectDataForWatchpointCommandCallback(
"This script interpreter does not support watchpoint callbacks.");
}
-bool ScriptInterpreter::LoadScriptingModule(
- const char *filename, bool init_session, lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp) {
+bool ScriptInterpreter::LoadScriptingModule(const char *filename,
+ bool init_session,
+ lldb_private::Status &error,
+ StructuredData::ObjectSP *module_sp,
+ FileSpec extra_search_dir) {
error.SetErrorString(
"This script interpreter does not support importing modules.");
return false;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
index 8dee6b48453a..d36aeca21c69 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
@@ -39,6 +39,12 @@ ABIAArch64::GetEHAndDWARFNums(llvm::StringRef name) {
return MCBasedABI::GetEHAndDWARFNums(name);
}
+std::string ABIAArch64::GetMCName(std::string reg) {
+ MapRegisterName(reg, "v", "q");
+ MapRegisterName(reg, "x29", "fp");
+ MapRegisterName(reg, "x30", "lr");
+ return reg;
+}
uint32_t ABIAArch64::GetGenericNum(llvm::StringRef name) {
return llvm::StringSwitch<uint32_t>(name)
.Case("pc", LLDB_REGNUM_GENERIC_PC)
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
index 981145e2017e..bdff648f1b52 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
@@ -20,10 +20,7 @@ protected:
std::pair<uint32_t, uint32_t>
GetEHAndDWARFNums(llvm::StringRef name) override;
- std::string GetMCName(std::string reg) override {
- MapRegisterName(reg, "v", "q");
- return reg;
- }
+ std::string GetMCName(std::string reg) override;
uint32_t GetGenericNum(llvm::StringRef name) override;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
index 983da26a2a6d..09b319a84a08 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
@@ -492,7 +492,8 @@ static bool LoadValueFromConsecutiveGPRRegisters(
uint32_t &NGRN, // NGRN (see ABI documentation)
uint32_t &NSRN, // NSRN (see ABI documentation)
DataExtractor &data) {
- llvm::Optional<uint64_t> byte_size = value_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> byte_size =
+ value_type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
if (!byte_size || *byte_size == 0)
return false;
@@ -509,7 +510,8 @@ static bool LoadValueFromConsecutiveGPRRegisters(
if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) {
if (!base_type)
return false;
- llvm::Optional<uint64_t> base_byte_size = base_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> base_byte_size =
+ base_type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
if (!base_byte_size)
return false;
uint32_t data_offset = 0;
@@ -646,7 +648,7 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
return return_valobj_sp;
llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
+ return_compiler_type.GetByteSize(&thread);
if (!byte_size)
return return_valobj_sp;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
index 831c8aa0d760..1214195dcfc0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
@@ -466,7 +466,8 @@ static bool LoadValueFromConsecutiveGPRRegisters(
uint32_t &NGRN, // NGRN (see ABI documentation)
uint32_t &NSRN, // NSRN (see ABI documentation)
DataExtractor &data) {
- llvm::Optional<uint64_t> byte_size = value_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> byte_size =
+ value_type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
if (byte_size || *byte_size == 0)
return false;
@@ -484,7 +485,8 @@ static bool LoadValueFromConsecutiveGPRRegisters(
if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) {
if (!base_type)
return false;
- llvm::Optional<uint64_t> base_byte_size = base_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> base_byte_size =
+ base_type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
if (!base_byte_size)
return false;
uint32_t data_offset = 0;
@@ -614,7 +616,7 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
return return_valobj_sp;
llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
+ return_compiler_type.GetByteSize(&thread);
if (!byte_size)
return return_valobj_sp;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp
index a212eef2ab8a..be8586722d8f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp
@@ -272,7 +272,8 @@ bool ABISysV_arc::PrepareTrivialCall(Thread &thread, addr_t sp, addr_t pc,
reg_value[byte_index++] = 0;
}
- RegisterValue reg_val_obj(reg_value, reg_size, eByteOrderLittle);
+ RegisterValue reg_val_obj(llvm::makeArrayRef(reg_value, reg_size),
+ eByteOrderLittle);
if (!reg_ctx->WriteRegister(
reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_index),
reg_val_obj))
@@ -458,7 +459,7 @@ ABISysV_arc::GetReturnValueObjectSimple(Thread &thread,
const uint32_t type_flags = compiler_type.GetTypeInfo();
// Integer return type.
if (type_flags & eTypeIsInteger) {
- const size_t byte_size = compiler_type.GetByteSize(nullptr).getValueOr(0);
+ const size_t byte_size = compiler_type.GetByteSize(&thread).getValueOr(0);
auto raw_value = ReadRawValue(reg_ctx, byte_size);
const bool is_signed = (type_flags & eTypeIsSigned) != 0;
@@ -482,7 +483,7 @@ ABISysV_arc::GetReturnValueObjectSimple(Thread &thread,
if (compiler_type.IsFloatingPointType(float_count, is_complex) &&
1 == float_count && !is_complex) {
- const size_t byte_size = compiler_type.GetByteSize(nullptr).getValueOr(0);
+ const size_t byte_size = compiler_type.GetByteSize(&thread).getValueOr(0);
auto raw_value = ReadRawValue(reg_ctx, byte_size);
if (!SetSizedFloat(value.GetScalar(), raw_value, byte_size))
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp
index ef500cb198a8..06c4590b7740 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp
@@ -34,7 +34,7 @@
using namespace lldb;
using namespace lldb_private;
-static RegisterInfo g_register_infos[] = {
+static const RegisterInfo g_register_infos[] = {
// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
// DWARF GENERIC PROCESS PLUGIN
// LLDB NATIVE
@@ -1292,24 +1292,9 @@ static RegisterInfo g_register_infos[] = {
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 *
ABIMacOSX_arm::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;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp
index 1a93bac564f7..26b3152bed16 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp
@@ -36,7 +36,7 @@ using namespace lldb_private;
LLDB_PLUGIN_DEFINE(ABISysV_arm)
-static RegisterInfo g_register_infos[] = {
+static const RegisterInfo g_register_infos[] = {
// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
// DWARF GENERIC PROCESS PLUGIN
// LLDB NATIVE VALUE REGS INVALIDATE REGS
@@ -1295,24 +1295,9 @@ static RegisterInfo g_register_infos[] = {
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_arm::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;
}
@@ -1718,7 +1703,7 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
if (homogeneous_count > 0 && homogeneous_count <= 4) {
llvm::Optional<uint64_t> base_byte_size =
- base_type.GetByteSize(nullptr);
+ base_type.GetByteSize(&thread);
if (base_type.IsVectorType(nullptr, nullptr)) {
if (base_byte_size &&
(*base_byte_size == 8 || *base_byte_size == 16)) {
@@ -1747,7 +1732,7 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
if (base_type.IsFloatingPointType(float_count, is_complex)) {
llvm::Optional<uint64_t> base_byte_size =
- base_type.GetByteSize(nullptr);
+ base_type.GetByteSize(&thread);
if (float_count == 2 && is_complex) {
if (index != 0 && base_byte_size &&
vfp_byte_size != *base_byte_size)
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp
index 32313d4cd815..47aaefd3b228 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp
@@ -34,7 +34,7 @@ using namespace lldb_private;
LLDB_PLUGIN_DEFINE_ADV(ABISysV_hexagon, ABIHexagon)
-static RegisterInfo g_register_infos[] = {
+static const RegisterInfo g_register_infos[] = {
// hexagon-core.xml
{"r00",
"",
@@ -974,24 +974,9 @@ static RegisterInfo g_register_infos[] = {
static const uint32_t k_num_register_infos =
sizeof(g_register_infos) / sizeof(RegisterInfo);
-static bool g_register_info_names_constified = false;
const lldb_private::RegisterInfo *
ABISysV_hexagon::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;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp
index bb28a50e5f4a..751555722dac 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp
@@ -753,7 +753,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
const ArchSpec target_arch = target->GetArchitecture();
ByteOrder target_byte_order = target_arch.GetByteOrder();
llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
+ return_compiler_type.GetByteSize(&thread);
if (!byte_size)
return return_valobj_sp;
const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
@@ -962,7 +962,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
return_compiler_type.GetFieldAtIndex(
idx, name, &field_bit_offset, nullptr, nullptr);
llvm::Optional<uint64_t> field_byte_width =
- field_compiler_type.GetByteSize(nullptr);
+ field_compiler_type.GetByteSize(&thread);
if (!field_byte_width)
return return_valobj_sp;
@@ -1034,7 +1034,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
idx, name, &field_bit_offset, nullptr, nullptr);
llvm::Optional<uint64_t> field_byte_width =
- field_compiler_type.GetByteSize(nullptr);
+ field_compiler_type.GetByteSize(&thread);
// if we don't know the size of the field (e.g. invalid type), just
// bail out
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp
index 6f5eded7b031..91d2e59ed632 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp
@@ -527,7 +527,7 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple(
// Extract the register context so we can read arguments from registers
llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
+ return_compiler_type.GetByteSize(&thread);
if (!byte_size)
return return_valobj_sp;
uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
@@ -574,7 +574,7 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple(
// Don't handle complex yet.
} else {
llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
+ return_compiler_type.GetByteSize(&thread);
if (byte_size && *byte_size <= sizeof(long double)) {
const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
RegisterValue f1_value;
@@ -608,7 +608,7 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
} else if (type_flags & eTypeIsVector) {
llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
+ return_compiler_type.GetByteSize(&thread);
if (byte_size && *byte_size > 0) {
const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
if (altivec_reg) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp
index 251ac972fd76..c7cb7736df9f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp
@@ -567,7 +567,7 @@ private:
ReturnValueExtractor(Thread &thread, CompilerType &type,
RegisterContext *reg_ctx, ProcessSP process_sp)
: m_thread(thread), m_type(type),
- m_byte_size(m_type.GetByteSize(nullptr).getValueOr(0)),
+ m_byte_size(m_type.GetByteSize(&thread).getValueOr(0)),
m_data_up(new DataBufferHeap(m_byte_size, 0)), m_reg_ctx(reg_ctx),
m_process_sp(process_sp), m_byte_order(process_sp->GetByteOrder()),
m_addr_size(
@@ -643,7 +643,7 @@ private:
DataExtractor de(&raw_data, sizeof(raw_data), m_byte_order, m_addr_size);
offset_t offset = 0;
- llvm::Optional<uint64_t> byte_size = type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> byte_size = type.GetByteSize(m_process_sp.get());
if (!byte_size)
return {};
switch (*byte_size) {
@@ -777,7 +777,8 @@ private:
CompilerType elem_type;
if (m_type.IsHomogeneousAggregate(&elem_type)) {
uint32_t type_flags = elem_type.GetTypeInfo();
- llvm::Optional<uint64_t> elem_size = elem_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> elem_size =
+ elem_type.GetByteSize(m_process_sp.get());
if (!elem_size)
return {};
if (type_flags & eTypeIsComplex || !(type_flags & eTypeIsFloat)) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp
index eced2adc7591..22a64170017b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp
@@ -118,7 +118,7 @@ enum dwarf_regnums {
nullptr, nullptr, nullptr, 0 \
}
-static RegisterInfo g_register_infos[] = {
+static const 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),
@@ -173,24 +173,9 @@ static RegisterInfo g_register_infos[] = {
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;
}
@@ -508,7 +493,7 @@ ValueObjectSP ABISysV_s390x::GetReturnValueObjectSimple(
if (type_flags & eTypeIsInteger) {
// Extract the register context so we can read arguments from registers.
llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
+ return_compiler_type.GetByteSize(&thread);
if (!byte_size)
return return_valobj_sp;
uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
@@ -555,7 +540,7 @@ ValueObjectSP ABISysV_s390x::GetReturnValueObjectSimple(
// Don't handle complex yet.
} else {
llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
+ return_compiler_type.GetByteSize(&thread);
if (byte_size && *byte_size <= sizeof(long double)) {
const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
RegisterValue f0_value;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp
index 2ac87d1512e9..2f47d3f462d2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp
@@ -387,7 +387,7 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
{
value.SetValueType(Value::eValueTypeScalar);
llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
+ return_compiler_type.GetByteSize(&thread);
if (!byte_size)
return return_valobj_sp;
bool success = false;
@@ -512,7 +512,7 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
} else if (type_flags & eTypeIsVector) // 'Packed'
{
llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
+ return_compiler_type.GetByteSize(&thread);
if (byte_size && *byte_size > 0) {
const RegisterInfo *vec_reg = reg_ctx->GetRegisterInfoByName("xmm0", 0);
if (vec_reg == nullptr)
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp
index 7729e58f8580..2aa2c02b2e87 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp
@@ -406,7 +406,7 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple(
// Extract the register context so we can read arguments from registers
llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
+ return_compiler_type.GetByteSize(&thread);
if (!byte_size)
return return_valobj_sp;
uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
@@ -453,7 +453,7 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple(
// Don't handle complex yet.
} else {
llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
+ return_compiler_type.GetByteSize(&thread);
if (byte_size && *byte_size <= sizeof(long double)) {
const RegisterInfo *xmm0_info =
reg_ctx->GetRegisterInfoByName("xmm0", 0);
@@ -492,7 +492,7 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
} else if (type_flags & eTypeIsVector) {
llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
+ return_compiler_type.GetByteSize(&thread);
if (byte_size && *byte_size > 0) {
const RegisterInfo *altivec_reg =
reg_ctx->GetRegisterInfoByName("xmm0", 0);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp
index 63b670b07277..06e0ce40836d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp
@@ -414,7 +414,7 @@ ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectSimple(
if (type_flags & eTypeIsInteger) {
// Extract the register context so we can read arguments from registers
llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
+ return_compiler_type.GetByteSize(&thread);
if (!byte_size)
return return_valobj_sp;
uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
@@ -461,7 +461,7 @@ ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectSimple(
// Don't handle complex yet.
} else {
llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
+ return_compiler_type.GetByteSize(&thread);
if (byte_size && *byte_size <= sizeof(long double)) {
const RegisterInfo *xmm0_info =
reg_ctx->GetRegisterInfoByName("xmm0", 0);
@@ -499,7 +499,7 @@ ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectSimple(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
} else if (type_flags & eTypeIsVector) {
llvm::Optional<uint64_t> byte_size =
- return_compiler_type.GetByteSize(nullptr);
+ return_compiler_type.GetByteSize(&thread);
if (byte_size && *byte_size > 0) {
const RegisterInfo *xmm_reg =
reg_ctx->GetRegisterInfoByName("xmm0", 0);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
index 6427d8d176c8..8a2d3232a39a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
@@ -1056,7 +1056,7 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
thumb_arch_name.erase(0, 3);
thumb_arch_name.insert(0, "thumb");
} else {
- thumb_arch_name = "thumbv8.2a";
+ thumb_arch_name = "thumbv8.7a";
}
thumb_arch.GetTriple().setArchName(llvm::StringRef(thumb_arch_name));
}
@@ -1068,7 +1068,7 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
// specified)
if (triple.getArch() == llvm::Triple::arm &&
triple.getSubArch() == llvm::Triple::NoSubArch)
- triple.setArchName("armv8.2a");
+ triple.setArchName("armv8.7a");
std::string features_str = "";
const char *triple_str = triple.getTriple().c_str();
@@ -1137,16 +1137,13 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
features_str += "+dspr2,";
}
- // If any AArch64 variant, enable the ARMv8.5 ISA with SVE extensions so we
- // can disassemble newer instructions.
- if (triple.getArch() == llvm::Triple::aarch64 ||
- triple.getArch() == llvm::Triple::aarch64_32)
- features_str += "+v8.5a,+sve2";
+ // If any AArch64 variant, enable latest ISA with any optional
+ // extensions like SVE.
+ if (triple.isAArch64()) {
+ features_str += "+v8.7a,+sve2,+mte";
- if ((triple.getArch() == llvm::Triple::aarch64 ||
- triple.getArch() == llvm::Triple::aarch64_32)
- && triple.getVendor() == llvm::Triple::Apple) {
- cpu = "apple-latest";
+ if (triple.getVendor() == llvm::Triple::Apple)
+ cpu = "apple-latest";
}
// We use m_disasm_up.get() to tell whether we are valid or not, so if this
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
index 2d39ce06a8d9..2570e003fd6a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
@@ -131,10 +131,6 @@ protected:
private:
const lldb_private::SectionList *
GetSectionListFromModule(const lldb::ModuleSP module) const;
-
- DynamicLoaderHexagonDYLD(const DynamicLoaderHexagonDYLD &) = delete;
- const DynamicLoaderHexagonDYLD &
- operator=(const DynamicLoaderHexagonDYLD &) = delete;
};
#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_DYNAMICLOADERHEXAGONDYLD_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
index af76056af684..5e2a866adb22 100644
--- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
@@ -246,7 +246,7 @@ std::string HexagonDYLDRendezvous::ReadStringFromMemory(addr_t addr) {
return std::string();
for (;;) {
- size = m_process->DoReadMemory(addr, &c, 1, error);
+ size = m_process->ReadMemory(addr, &c, 1, error);
if (size != 1 || error.Fail())
return std::string();
if (c == 0)
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index 15b3805003a5..866acbddbdc8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -94,12 +94,13 @@ DYLDRendezvous::DYLDRendezvous(Process *process)
: m_process(process), m_rendezvous_addr(LLDB_INVALID_ADDRESS), m_current(),
m_previous(), m_loaded_modules(), m_soentries(), m_added_soentries(),
m_removed_soentries() {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
-
m_thread_info.valid = false;
+ UpdateExecutablePath();
+}
- // Cache a copy of the executable path
+void DYLDRendezvous::UpdateExecutablePath() {
if (m_process) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer();
if (exe_mod) {
m_exe_file_spec = exe_mod->GetPlatformFileSpec();
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
index b028120eb0d4..3e88d88f407a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
@@ -60,6 +60,9 @@ public:
DYLDRendezvous(lldb_private::Process *process);
+ /// Update the cached executable path.
+ void UpdateExecutablePath();
+
/// Update the internal snapshot of runtime linker rendezvous and recompute
/// the currently loaded modules.
///
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index ac60af5336ed..160faa74af23 100644
--- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -76,7 +76,8 @@ DynamicLoaderPOSIXDYLD::DynamicLoaderPOSIXDYLD(Process *process)
m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS),
m_auxv(), m_dyld_bid(LLDB_INVALID_BREAK_ID),
m_vdso_base(LLDB_INVALID_ADDRESS),
- m_interpreter_base(LLDB_INVALID_ADDRESS) {}
+ m_interpreter_base(LLDB_INVALID_ADDRESS), m_initial_modules_added(false) {
+}
DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() {
if (m_dyld_bid != LLDB_INVALID_BREAK_ID) {
@@ -101,6 +102,7 @@ void DynamicLoaderPOSIXDYLD::DidAttach() {
ModuleSP executable_sp = GetTargetExecutable();
ResolveExecutableModule(executable_sp);
+ m_rendezvous.UpdateExecutablePath();
// find the main process load offset
addr_t load_offset = ComputeLoadOffset();
@@ -418,14 +420,38 @@ void DynamicLoaderPOSIXDYLD::RefreshModules() {
ModuleList &loaded_modules = m_process->GetTarget().GetImages();
- if (m_rendezvous.ModulesDidLoad()) {
+ if (m_rendezvous.ModulesDidLoad() || !m_initial_modules_added) {
ModuleList new_modules;
- E = m_rendezvous.loaded_end();
- for (I = m_rendezvous.loaded_begin(); I != E; ++I) {
+ // If this is the first time rendezvous breakpoint fires, we need
+ // to take care of adding all the initial modules reported by
+ // the loader. This is necessary to list ld-linux.so on Linux,
+ // and all DT_NEEDED entries on *BSD.
+ if (m_initial_modules_added) {
+ I = m_rendezvous.loaded_begin();
+ E = m_rendezvous.loaded_end();
+ } else {
+ I = m_rendezvous.begin();
+ E = m_rendezvous.end();
+ m_initial_modules_added = true;
+ }
+ for (; I != E; ++I) {
ModuleSP module_sp =
LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
if (module_sp.get()) {
+ if (module_sp->GetObjectFile()->GetBaseAddress().GetLoadAddress(
+ &m_process->GetTarget()) == m_interpreter_base &&
+ module_sp != m_interpreter_module.lock()) {
+ // If this is a duplicate instance of ld.so, unload it. We may end up
+ // with it if we load it via a different path than before (symlink
+ // vs real path).
+ // TODO: remove this once we either fix library matching or avoid
+ // loading the interpreter when setting the rendezvous breakpoint.
+ UnloadSections(module_sp);
+ loaded_modules.Remove(module_sp);
+ continue;
+ }
+
loaded_modules.AppendIfNeeded(module_sp);
new_modules.Append(module_sp);
}
@@ -544,6 +570,7 @@ ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() {
true /* notify */)) {
UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_interpreter_base,
false);
+ m_interpreter_module = module_sp;
return module_sp;
}
return nullptr;
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
index a7fcdfbadeaf..61567801fdd0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
@@ -81,6 +81,9 @@ protected:
/// mapped to the address space
lldb::addr_t m_interpreter_base;
+ /// Contains the pointer to the interpret module, if loaded.
+ std::weak_ptr<lldb_private::Module> m_interpreter_module;
+
/// Loaded module list. (link map for each module)
std::map<lldb::ModuleWP, lldb::addr_t, std::owner_less<lldb::ModuleWP>>
m_loaded_modules;
@@ -95,6 +98,9 @@ protected:
void *baton, lldb_private::StoppointCallbackContext *context,
lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+ /// Indicates whether the initial set of modules was reported added.
+ bool m_initial_modules_added;
+
/// Helper method for RendezvousBreakpointHit. Updates LLDB's current set
/// of loaded modules.
void RefreshModules();
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
index 48762fe6e0c3..c1fceeb1482c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
@@ -63,9 +63,6 @@ DynamicLoader *DynamicLoaderStatic::CreateInstance(Process *process,
DynamicLoaderStatic::DynamicLoaderStatic(Process *process)
: DynamicLoader(process) {}
-// Destructor
-DynamicLoaderStatic::~DynamicLoaderStatic() {}
-
/// Called after attaching a process.
///
/// Allow DynamicLoader plug-ins to execute some code after
@@ -86,11 +83,7 @@ void DynamicLoaderStatic::LoadAllImagesAtFileAddresses() {
// Disable JIT for static dynamic loader targets
m_process->SetCanJIT(false);
- 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) {
- ModuleSP module_sp(module_list.GetModuleAtIndexUnlocked(idx));
+ for (ModuleSP module_sp : module_list.Modules()) {
if (module_sp) {
bool changed = false;
ObjectFile *image_object_file = module_sp->GetObjectFile();
diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
index ce78804f9a92..1a36c7851c2a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
+++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
@@ -18,8 +18,6 @@ class DynamicLoaderStatic : public lldb_private::DynamicLoader {
public:
DynamicLoaderStatic(lldb_private::Process *process);
- ~DynamicLoaderStatic() override;
-
// Static Functions
static void Initialize();
@@ -52,9 +50,6 @@ public:
private:
void LoadAllImagesAtFileAddresses();
-
- DynamicLoaderStatic(const DynamicLoaderStatic &) = delete;
- const DynamicLoaderStatic &operator=(const DynamicLoaderStatic &) = delete;
};
#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_STATIC_DYNAMICLOADERSTATIC_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
index 39ba5f4e9e4f..3edbc4ab98c0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
@@ -443,7 +443,9 @@ void ASTResultSynthesizer::CommitPersistentDecls() {
return;
auto *persistent_vars = llvm::cast<ClangPersistentVariables>(state);
- TypeSystemClang *scratch_ctx = TypeSystemClang::GetScratch(m_target);
+
+ TypeSystemClang *scratch_ctx = ScratchTypeSystemClang::GetForTarget(
+ m_target, m_ast_context->getLangOpts());
for (clang::NamedDecl *decl : m_decls) {
StringRef name = decl->getName();
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h
index 3787c572d45b..b70ec223df4d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h
@@ -359,15 +359,12 @@ public:
}
void CompleteType(clang::TagDecl *Tag) override {
- while (!Tag->isCompleteDefinition())
- for (size_t i = 0; i < Sources.size(); ++i) {
- // FIXME: We are technically supposed to loop here too until
- // Tag->isCompleteDefinition() is true, but if our low quality source
- // is failing to complete the tag this code will deadlock.
- Sources[i]->CompleteType(Tag);
- if (Tag->isCompleteDefinition())
- break;
- }
+ for (clang::ExternalSemaSource *S : Sources) {
+ S->CompleteType(Tag);
+ // Stop after the first source completed the type.
+ if (Tag->isCompleteDefinition())
+ break;
+ }
}
void CompleteType(clang::ObjCInterfaceDecl *Class) override {
@@ -404,13 +401,6 @@ public:
return nullptr;
}
- bool DeclIsFromPCHWithObjectFile(const clang::Decl *D) override {
- for (auto *S : Sources)
- if (S->DeclIsFromPCHWithObjectFile(D))
- return true;
- return false;
- }
-
bool layoutRecordType(
const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
index ac16738933ac..e2601a059bb7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
@@ -216,7 +216,12 @@ namespace {
/// imported while completing the original Decls).
class CompleteTagDeclsScope : public ClangASTImporter::NewDeclListener {
ClangASTImporter::ImporterDelegateSP m_delegate;
- llvm::SmallVector<NamedDecl *, 32> m_decls_to_complete;
+ /// List of declarations in the target context that need to be completed.
+ /// Every declaration should only be completed once and therefore should only
+ /// be once in this list.
+ llvm::SetVector<NamedDecl *> m_decls_to_complete;
+ /// Set of declarations that already were successfully completed (not just
+ /// added to m_decls_to_complete).
llvm::SmallPtrSet<NamedDecl *, 32> m_decls_already_completed;
clang::ASTContext *m_dst_ctx;
clang::ASTContext *m_src_ctx;
@@ -244,10 +249,13 @@ public:
NamedDecl *decl = m_decls_to_complete.pop_back_val();
m_decls_already_completed.insert(decl);
+ // The decl that should be completed has to be imported into the target
+ // context from some other context.
+ assert(to_context_md->hasOrigin(decl));
// We should only complete decls coming from the source context.
- assert(to_context_md->m_origins[decl].ctx == m_src_ctx);
+ assert(to_context_md->getOrigin(decl).ctx == m_src_ctx);
- Decl *original_decl = to_context_md->m_origins[decl].decl;
+ Decl *original_decl = to_context_md->getOrigin(decl).decl;
// Complete the decl now.
TypeSystemClang::GetCompleteDecl(m_src_ctx, original_decl);
@@ -266,7 +274,7 @@ public:
container_decl->setHasExternalVisibleStorage(false);
}
- to_context_md->m_origins.erase(decl);
+ to_context_md->removeOrigin(decl);
}
// Stop listening to imported decls. We do this after clearing the
@@ -287,7 +295,8 @@ public:
// Check if we already completed this type.
if (m_decls_already_completed.count(to_named_decl) != 0)
return;
- m_decls_to_complete.push_back(to_named_decl);
+ // Queue this type to be completed.
+ m_decls_to_complete.insert(to_named_decl);
}
};
} // namespace
@@ -581,10 +590,7 @@ bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl,
ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
- OriginMap &origins = context_md->m_origins;
-
- origins[decl] = DeclOrigin(origin_ast_ctx, origin_decl);
-
+ context_md->setOrigin(decl, DeclOrigin(origin_ast_ctx, origin_decl));
return true;
}
@@ -721,29 +727,14 @@ ClangASTImporter::DeclOrigin
ClangASTImporter::GetDeclOrigin(const clang::Decl *decl) {
ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
- OriginMap &origins = context_md->m_origins;
-
- OriginMap::iterator iter = origins.find(decl);
-
- if (iter != origins.end())
- return iter->second;
- return DeclOrigin();
+ return context_md->getOrigin(decl);
}
void ClangASTImporter::SetDeclOrigin(const clang::Decl *decl,
clang::Decl *original_decl) {
ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
-
- OriginMap &origins = context_md->m_origins;
-
- OriginMap::iterator iter = origins.find(decl);
-
- if (iter != origins.end()) {
- iter->second.decl = original_decl;
- iter->second.ctx = &original_decl->getASTContext();
- return;
- }
- origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl);
+ context_md->setOrigin(
+ decl, DeclOrigin(&original_decl->getASTContext(), original_decl));
}
void ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl,
@@ -817,14 +808,7 @@ void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast,
return;
md->m_delegates.erase(src_ast);
-
- for (OriginMap::iterator iter = md->m_origins.begin();
- iter != md->m_origins.end();) {
- if (iter->second.ctx == src_ast)
- md->m_origins.erase(iter++);
- else
- ++iter;
- }
+ md->removeOriginsWithContext(src_ast);
}
ClangASTImporter::MapCompleter::~MapCompleter() { return; }
@@ -895,13 +879,14 @@ ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) {
return dn_or_err.takeError();
DeclContext *dc = *dc_or_err;
DeclContext::lookup_result lr = dc->lookup(*dn_or_err);
- if (lr.size()) {
- clang::Decl *lookup_found = lr.front();
- RegisterImportedDecl(From, lookup_found);
- m_decls_to_ignore.insert(lookup_found);
- return lookup_found;
- } else
- LLDB_LOG(log, "[ClangASTImporter] Complete definition not found");
+ for (clang::Decl *candidate : lr) {
+ if (candidate->getKind() == From->getKind()) {
+ RegisterImportedDecl(From, candidate);
+ m_decls_to_ignore.insert(candidate);
+ return candidate;
+ }
+ }
+ LLDB_LOG(log, "[ClangASTImporter] Complete definition not found");
}
return ASTImporter::ImportImpl(From);
@@ -1100,37 +1085,31 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
m_master.MaybeGetContextMetadata(m_source_ctx);
if (from_context_md) {
- OriginMap &origins = from_context_md->m_origins;
-
- OriginMap::iterator origin_iter = origins.find(from);
+ DeclOrigin origin = from_context_md->getOrigin(from);
- if (origin_iter != origins.end()) {
- if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
- user_id != LLDB_INVALID_UID) {
- if (origin_iter->second.ctx != &to->getASTContext())
- to_context_md->m_origins[to] = origin_iter->second;
- }
+ if (origin.Valid()) {
+ if (!to_context_md->hasOrigin(to) || user_id != LLDB_INVALID_UID)
+ if (origin.ctx != &to->getASTContext())
+ to_context_md->setOrigin(to, origin);
ImporterDelegateSP direct_completer =
- m_master.GetDelegate(&to->getASTContext(), origin_iter->second.ctx);
+ m_master.GetDelegate(&to->getASTContext(), origin.ctx);
if (direct_completer.get() != this)
- direct_completer->ASTImporter::Imported(origin_iter->second.decl, to);
+ direct_completer->ASTImporter::Imported(origin.decl, to);
LLDB_LOG(log,
" [ClangASTImporter] Propagated origin "
"(Decl*){0}/(ASTContext*){1} from (ASTContext*){2} to "
"(ASTContext*){3}",
- origin_iter->second.decl, origin_iter->second.ctx,
- &from->getASTContext(), &to->getASTContext());
+ origin.decl, origin.ctx, &from->getASTContext(),
+ &to->getASTContext());
} else {
if (m_new_decl_listener)
m_new_decl_listener->NewDeclImported(from, to);
- if (to_context_md->m_origins.find(to) == to_context_md->m_origins.end() ||
- user_id != LLDB_INVALID_UID) {
- to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
- }
+ if (!to_context_md->hasOrigin(to) || user_id != LLDB_INVALID_UID)
+ to_context_md->setOrigin(to, DeclOrigin(m_source_ctx, from));
LLDB_LOG(log,
" [ClangASTImporter] Decl has no origin information in "
@@ -1151,7 +1130,7 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
namespace_map_iter->second;
}
} else {
- to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
+ to_context_md->setOrigin(to, DeclOrigin(m_source_ctx, from));
LLDB_LOG(log,
" [ClangASTImporter] Sourced origin "
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h
index 6ceec774914b..bf4ad174cf9c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h
@@ -160,14 +160,12 @@ public:
decl = rhs.decl;
}
- bool Valid() { return (ctx != nullptr || decl != nullptr); }
+ bool Valid() const { return (ctx != nullptr || decl != nullptr); }
clang::ASTContext *ctx;
clang::Decl *decl;
};
- typedef llvm::DenseMap<const clang::Decl *, DeclOrigin> OriginMap;
-
/// Listener interface used by the ASTImporterDelegate to inform other code
/// about decls that have been imported the first time.
struct NewDeclListener {
@@ -259,17 +257,61 @@ public:
typedef llvm::DenseMap<const clang::NamespaceDecl *, NamespaceMapSP>
NamespaceMetaMap;
- struct ASTContextMetadata {
- ASTContextMetadata(clang::ASTContext *dst_ctx)
- : m_dst_ctx(dst_ctx), m_delegates(), m_origins(), m_namespace_maps(),
- m_map_completer(nullptr) {}
+ class ASTContextMetadata {
+ typedef llvm::DenseMap<const clang::Decl *, DeclOrigin> OriginMap;
+
+ public:
+ ASTContextMetadata(clang::ASTContext *dst_ctx) : m_dst_ctx(dst_ctx) {}
clang::ASTContext *m_dst_ctx;
DelegateMap m_delegates;
- OriginMap m_origins;
NamespaceMetaMap m_namespace_maps;
- MapCompleter *m_map_completer;
+ MapCompleter *m_map_completer = nullptr;
+
+ /// Sets the DeclOrigin for the given Decl and overwrites any existing
+ /// DeclOrigin.
+ void setOrigin(const clang::Decl *decl, DeclOrigin origin) {
+ m_origins[decl] = origin;
+ }
+
+ /// Removes any tracked DeclOrigin for the given decl.
+ void removeOrigin(const clang::Decl *decl) { m_origins.erase(decl); }
+
+ /// Remove all DeclOrigin entries that point to the given ASTContext.
+ /// Useful when an ASTContext is about to be deleted and all the dangling
+ /// pointers to it need to be removed.
+ void removeOriginsWithContext(clang::ASTContext *ctx) {
+ for (OriginMap::iterator iter = m_origins.begin();
+ iter != m_origins.end();) {
+ if (iter->second.ctx == ctx)
+ m_origins.erase(iter++);
+ else
+ ++iter;
+ }
+ }
+
+ /// Returns the DeclOrigin for the given Decl or an invalid DeclOrigin
+ /// instance if there no known DeclOrigin for the given Decl.
+ DeclOrigin getOrigin(const clang::Decl *decl) const {
+ auto iter = m_origins.find(decl);
+ if (iter == m_origins.end())
+ return DeclOrigin();
+ return iter->second;
+ }
+
+ /// Returns true there is a known DeclOrigin for the given Decl.
+ bool hasOrigin(const clang::Decl *decl) const {
+ return getOrigin(decl).Valid();
+ }
+
+ private:
+ /// Maps declarations to the ASTContext/Decl from which they were imported
+ /// from. If a declaration is from an ASTContext which has been deleted
+ /// since the declaration was imported or the declaration wasn't created by
+ /// the ASTImporter, then it doesn't have a DeclOrigin and will not be
+ /// tracked here.
+ OriginMap m_origins;
};
typedef std::shared_ptr<ASTContextMetadata> ASTContextMetadataSP;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index 6fe85a1298fc..0f34c48c7e82 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -71,20 +71,22 @@ ClangASTSource::~ClangASTSource() {
if (!m_target)
return;
- // We are in the process of destruction, don't create clang ast context on
- // demand by passing false to
- // Target::GetScratchTypeSystemClang(create_on_demand).
- TypeSystemClang *scratch_clang_ast_context =
- TypeSystemClang::GetScratch(*m_target, false);
- if (!scratch_clang_ast_context)
- return;
+ // Unregister the current ASTContext as a source for all scratch
+ // ASTContexts in the ClangASTImporter. Without this the scratch AST might
+ // query the deleted ASTContext for additional type information.
+ // We unregister from *all* scratch ASTContexts in case a type got exported
+ // to a scratch AST that isn't the best fitting scratch ASTContext.
+ TypeSystemClang *scratch_ast = ScratchTypeSystemClang::GetForTarget(
+ *m_target, ScratchTypeSystemClang::DefaultAST, false);
- clang::ASTContext &scratch_ast_context =
- scratch_clang_ast_context->getASTContext();
+ if (!scratch_ast)
+ return;
- if (m_ast_context != &scratch_ast_context && m_ast_importer_sp)
- m_ast_importer_sp->ForgetSource(&scratch_ast_context, m_ast_context);
+ ScratchTypeSystemClang *default_scratch_ast =
+ llvm::cast<ScratchTypeSystemClang>(scratch_ast);
+ // Unregister from the default scratch AST (and all sub-ASTs).
+ default_scratch_ast->ForgetSource(m_ast_context, *m_ast_importer_sp);
}
void ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer) {
@@ -482,6 +484,15 @@ void ClangASTSource::FindExternalLexicalDecls(
if (!copied_decl)
continue;
+ // FIXME: We should add the copied decl to the 'decls' list. This would
+ // add the copied Decl into the DeclContext and make sure that we
+ // correctly propagate that we added some Decls back to Clang.
+ // By leaving 'decls' empty we incorrectly return false from
+ // DeclContext::LoadLexicalDeclsFromExternalStorage which might cause
+ // lookup issues later on.
+ // We can't just add them for now as the ASTImporter already added the
+ // decl into the DeclContext and this would add it twice.
+
if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl)) {
QualType copied_field_type = copied_field->getType();
@@ -679,12 +690,7 @@ void ClangASTSource::FillNamespaceMap(
return;
}
- const ModuleList &target_images = m_target->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
-
- for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) {
- lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
-
+ for (lldb::ModuleSP image : m_target->GetImages().Modules()) {
if (!image)
continue;
@@ -1656,14 +1662,8 @@ void ClangASTSource::CompleteNamespaceMap(
module_sp->GetFileSpec().GetFilename());
}
} else {
- const ModuleList &target_images = m_target->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
-
CompilerDeclContext null_namespace_decl;
-
- for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) {
- lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
-
+ for (lldb::ModuleSP image : m_target->GetImages().Modules()) {
if (!image)
continue;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 8c49898e1d6c..852ce3bbd3db 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -19,6 +19,7 @@
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectVariable.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/Materializer.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/CompilerDecl.h"
@@ -109,7 +110,7 @@ bool ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx,
m_parser_vars->m_persistent_vars = llvm::cast<ClangPersistentVariables>(
target->GetPersistentExpressionStateForLanguage(eLanguageTypeC));
- if (!TypeSystemClang::GetScratch(*target))
+ if (!ScratchTypeSystemClang::GetForTarget(*target))
return false;
}
@@ -125,6 +126,12 @@ void ClangExpressionDeclMap::InstallCodeGenerator(
m_parser_vars->m_code_gen = code_gen;
}
+void ClangExpressionDeclMap::InstallDiagnosticManager(
+ DiagnosticManager &diag_manager) {
+ assert(m_parser_vars);
+ m_parser_vars->m_diagnostics = &diag_manager;
+}
+
void ClangExpressionDeclMap::DidParse() {
if (m_parser_vars && m_parser_vars->m_persistent_vars) {
for (size_t entity_index = 0, num_entities = m_found_entities.GetSize();
@@ -177,7 +184,7 @@ ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() {
TypeFromUser ClangExpressionDeclMap::DeportType(TypeSystemClang &target,
TypeSystemClang &source,
TypeFromParser parser_type) {
- assert(&target == TypeSystemClang::GetScratch(*m_target));
+ assert(&target == GetScratchContext(*m_target));
assert((TypeSystem *)&source == parser_type.GetTypeSystem());
assert(&source.getASTContext() == m_ast_context);
@@ -196,6 +203,17 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
if (ast == nullptr)
return false;
+ // Check if we already declared a persistent variable with the same name.
+ if (lldb::ExpressionVariableSP conflicting_var =
+ m_parser_vars->m_persistent_vars->GetVariable(name)) {
+ std::string msg = llvm::formatv("redefinition of persistent variable '{0}'",
+ name).str();
+ m_parser_vars->m_diagnostics->AddDiagnostic(
+ msg, DiagnosticSeverity::eDiagnosticSeverityError,
+ DiagnosticOrigin::eDiagnosticOriginLLDB);
+ return false;
+ }
+
if (m_parser_vars->m_materializer && is_result) {
Status err;
@@ -204,7 +222,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
if (target == nullptr)
return false;
- auto *clang_ast_context = TypeSystemClang::GetScratch(*target);
+ auto *clang_ast_context = GetScratchContext(*target);
if (!clang_ast_context)
return false;
@@ -242,7 +260,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
if (target == nullptr)
return false;
- TypeSystemClang *context = TypeSystemClang::GetScratch(*target);
+ TypeSystemClang *context = GetScratchContext(*target);
if (!context)
return false;
@@ -703,7 +721,7 @@ clang::NamedDecl *ClangExpressionDeclMap::GetPersistentDecl(ConstString name) {
if (!target)
return nullptr;
- TypeSystemClang::GetScratch(*target);
+ ScratchTypeSystemClang::GetForTarget(*target);
if (!m_parser_vars->m_persistent_vars)
return nullptr;
@@ -1620,7 +1638,7 @@ void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
if (target == nullptr)
return;
- TypeSystemClang *scratch_ast_context = TypeSystemClang::GetScratch(*target);
+ TypeSystemClang *scratch_ast_context = GetScratchContext(*target);
if (!scratch_ast_context)
return;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
index 6974535a8993..a9cd5d166b9d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -102,6 +102,8 @@ public:
void InstallCodeGenerator(clang::ASTConsumer *code_gen);
+ void InstallDiagnosticManager(DiagnosticManager &diag_manager);
+
/// Disable the state needed for parsing and IR transformation.
void DidParse();
@@ -330,6 +332,8 @@ private:
clang::ASTConsumer *m_code_gen = nullptr; ///< If non-NULL, a code generator
///that receives new top-level
///functions.
+ DiagnosticManager *m_diagnostics = nullptr;
+
private:
ParserVars(const ParserVars &) = delete;
const ParserVars &operator=(const ParserVars &) = delete;
@@ -376,6 +380,11 @@ private:
/// Deallocate struct variables
void DisableStructVars() { m_struct_vars.reset(); }
+ TypeSystemClang *GetScratchContext(Target &target) {
+ return ScratchTypeSystemClang::GetForTarget(target,
+ m_ast_context->getLangOpts());
+ }
+
/// Get this parser's ID for use in extracting parser- and JIT-specific data
/// from persistent variables.
uint64_t GetParserID() { return (uint64_t) this; }
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 6ff028cf6980..7644a5e1423e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -85,7 +85,7 @@
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Reproducer.h"
+#include "lldb/Utility/ReproducerProvider.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StringList.h"
@@ -302,6 +302,55 @@ static void SetupModuleHeaderPaths(CompilerInstance *compiler,
search_opts.ImplicitModuleMaps = true;
}
+/// Iff the given identifier is a C++ keyword, remove it from the
+/// identifier table (i.e., make the token a normal identifier).
+static void RemoveCppKeyword(IdentifierTable &idents, llvm::StringRef token) {
+ // FIXME: 'using' is used by LLDB for local variables, so we can't remove
+ // this keyword without breaking this functionality.
+ if (token == "using")
+ return;
+ // GCC's '__null' is used by LLDB to define NULL/Nil/nil.
+ if (token == "__null")
+ return;
+
+ LangOptions cpp_lang_opts;
+ cpp_lang_opts.CPlusPlus = true;
+ cpp_lang_opts.CPlusPlus11 = true;
+ cpp_lang_opts.CPlusPlus20 = true;
+
+ clang::IdentifierInfo &ii = idents.get(token);
+ // The identifier has to be a C++-exclusive keyword. if not, then there is
+ // nothing to do.
+ if (!ii.isCPlusPlusKeyword(cpp_lang_opts))
+ return;
+ // If the token is already an identifier, then there is nothing to do.
+ if (ii.getTokenID() == clang::tok::identifier)
+ return;
+ // Otherwise the token is a C++ keyword, so turn it back into a normal
+ // identifier.
+ ii.revertTokenIDToIdentifier();
+}
+
+/// Remove all C++ keywords from the given identifier table.
+static void RemoveAllCppKeywords(IdentifierTable &idents) {
+#define KEYWORD(NAME, FLAGS) RemoveCppKeyword(idents, llvm::StringRef(#NAME));
+#include "clang/Basic/TokenKinds.def"
+}
+
+/// Configures Clang diagnostics for the expression parser.
+static void SetupDefaultClangDiagnostics(CompilerInstance &compiler) {
+ // List of Clang warning groups that are not useful when parsing expressions.
+ const std::vector<const char *> groupsToIgnore = {
+ "unused-value",
+ "odr",
+ };
+ for (const char *group : groupsToIgnore) {
+ compiler.getDiagnostics().setSeverityForGroup(
+ clang::diag::Flavor::WarningOrError, group,
+ clang::diag::Severity::Ignored, SourceLocation());
+ }
+}
+
//===----------------------------------------------------------------------===//
// Implementation of ClangExpressionParser
//===----------------------------------------------------------------------===//
@@ -454,6 +503,10 @@ ClangExpressionParser::ClangExpressionParser(
// 4. Create and install the target on the compiler.
m_compiler->createDiagnostics();
+ // Limit the number of error diagnostics we emit.
+ // A value of 0 means no limit for both LLDB and Clang.
+ m_compiler->getDiagnostics().setErrorLimit(target_sp->GetExprErrorLimit());
+
auto target_info = TargetInfo::CreateTargetInfo(
m_compiler->getDiagnostics(), m_compiler->getInvocation().TargetOpts);
if (log) {
@@ -598,12 +651,7 @@ ClangExpressionParser::ClangExpressionParser(
m_compiler->getCodeGenOpts().setDebugInfo(codegenoptions::NoDebugInfo);
// Disable some warnings.
- m_compiler->getDiagnostics().setSeverityForGroup(
- clang::diag::Flavor::WarningOrError, "unused-value",
- clang::diag::Severity::Ignored, SourceLocation());
- m_compiler->getDiagnostics().setSeverityForGroup(
- clang::diag::Flavor::WarningOrError, "odr",
- clang::diag::Severity::Ignored, SourceLocation());
+ SetupDefaultClangDiagnostics(*m_compiler);
// Inform the target of the language options
//
@@ -623,6 +671,21 @@ ClangExpressionParser::ClangExpressionParser(
m_compiler->createSourceManager(m_compiler->getFileManager());
m_compiler->createPreprocessor(TU_Complete);
+ switch (language) {
+ case lldb::eLanguageTypeC:
+ case lldb::eLanguageTypeC89:
+ case lldb::eLanguageTypeC99:
+ case lldb::eLanguageTypeC11:
+ case lldb::eLanguageTypeObjC:
+ // This is not a C++ expression but we enabled C++ as explained above.
+ // Remove all C++ keywords from the PP so that the user can still use
+ // variables that have C++ keywords as names (e.g. 'int template;').
+ RemoveAllCppKeywords(m_compiler->getPreprocessor().getIdentifierTable());
+ break;
+ default:
+ break;
+ }
+
if (ClangModulesDeclVendor *decl_vendor =
target_sp->GetClangModulesDeclVendor()) {
if (auto *clang_persistent_vars = llvm::cast<ClangPersistentVariables>(
@@ -1010,8 +1073,8 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
if (file.Write(expr_text, bytes_written).Success()) {
if (bytes_written == expr_text_len) {
file.Close();
- if (auto fileEntry =
- m_compiler->getFileManager().getFile(result_path)) {
+ if (auto fileEntry = m_compiler->getFileManager().getOptionalFileRef(
+ result_path)) {
source_mgr.setMainFileID(source_mgr.createFileID(
*fileEntry,
SourceLocation(), SrcMgr::C_User));
@@ -1074,6 +1137,7 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap();
if (decl_map) {
decl_map->InstallCodeGenerator(&m_compiler->getASTConsumer());
+ decl_map->InstallDiagnosticManager(diagnostic_manager);
clang::ExternalASTSource *ast_source = decl_map->CreateProxy();
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
index a429963277d1..180e08b03c93 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
@@ -221,7 +221,7 @@ TokenVerifier::TokenVerifier(std::string body) {
clang::SourceManager SM(diags, file_mgr);
auto buf = llvm::MemoryBuffer::getMemBuffer(body);
- FileID FID = SM.createFileID(clang::SourceManager::Unowned, buf.get());
+ FileID FID = SM.createFileID(buf->getMemBufferRef());
// Let's just enable the latest ObjC and C++ which should get most tokens
// right.
@@ -231,7 +231,7 @@ TokenVerifier::TokenVerifier(std::string body) {
Opts.CPlusPlus17 = true;
Opts.LineComment = true;
- Lexer lex(FID, buf.get(), SM, Opts);
+ Lexer lex(FID, buf->getMemBufferRef(), SM, Opts);
Token token;
bool exit = false;
@@ -297,6 +297,7 @@ bool ClangExpressionSourceCode::GetText(
bool force_add_all_locals, llvm::ArrayRef<std::string> modules) const {
const char *target_specific_defines = "typedef signed char BOOL;\n";
std::string module_macros;
+ llvm::raw_string_ostream module_macros_stream(module_macros);
Target *target = exe_ctx.GetTargetPtr();
if (target) {
@@ -344,9 +345,13 @@ bool ClangExpressionSourceCode::GetText(
decl_vendor->ForEachMacro(
modules_for_macros,
- [&module_macros](const std::string &expansion) -> bool {
- module_macros.append(expansion);
- module_macros.append("\n");
+ [&module_macros_stream](llvm::StringRef token,
+ llvm::StringRef expansion) -> bool {
+ // Check if the macro hasn't already been defined in the
+ // g_expression_prefix (which defines a few builtin macros).
+ module_macros_stream << "#ifndef " << token << "\n";
+ module_macros_stream << expansion << "\n";
+ module_macros_stream << "#endif\n";
return false;
});
}
@@ -387,8 +392,8 @@ bool ClangExpressionSourceCode::GetText(
StreamString wrap_stream;
- wrap_stream.Printf("%s\n%s\n%s\n%s\n%s\n", module_macros.c_str(),
- debug_macros_stream.GetData(), g_expression_prefix,
+ wrap_stream.Printf("%s\n%s\n%s\n%s\n%s\n", g_expression_prefix,
+ module_macros.c_str(), debug_macros_stream.GetData(),
target_specific_defines, m_prefix.c_str());
// First construct a tagged form of the user expression so we can find it
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
index 8abb7e420575..b76fa6fbf690 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
@@ -137,14 +137,12 @@ bool lldb_private::ComputeClangResourceDirectory(FileSpec &lldb_shlib_spec,
FileSystem::Instance().Resolve(file_spec);
return true;
}
- raw_path = lldb_shlib_spec.GetPath();
}
- raw_path.resize(rev_it - r_end);
- } else {
- raw_path.resize(rev_it - r_end);
}
// Fall back to the Clang resource directory inside the framework.
+ raw_path = lldb_shlib_spec.GetPath();
+ raw_path.resize(rev_it - r_end);
raw_path.append("LLDB.framework/Resources/Clang");
file_spec.GetDirectory().SetString(raw_path.c_str());
FileSystem::Instance().Resolve(file_spec);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index 95acb883774d..c014ad504d37 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -33,7 +33,7 @@
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Reproducer.h"
+#include "lldb/Utility/ReproducerProvider.h"
#include "lldb/Utility/StreamString.h"
#include <memory>
@@ -95,8 +95,10 @@ public:
uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches,
std::vector<CompilerDecl> &decls) override;
- void ForEachMacro(const ModuleVector &modules,
- std::function<bool(const std::string &)> handler) override;
+ void ForEachMacro(
+ const ModuleVector &modules,
+ std::function<bool(llvm::StringRef, llvm::StringRef)> handler) override;
+
private:
void
ReportModuleExportsHelper(std::set<ClangModulesDeclVendor::ModuleID> &exports,
@@ -420,7 +422,7 @@ ClangModulesDeclVendorImpl::FindDecls(ConstString name, bool append,
void ClangModulesDeclVendorImpl::ForEachMacro(
const ClangModulesDeclVendor::ModuleVector &modules,
- std::function<bool(const std::string &)> handler) {
+ std::function<bool(llvm::StringRef, llvm::StringRef)> handler) {
if (!m_enabled) {
return;
}
@@ -490,7 +492,8 @@ void ClangModulesDeclVendorImpl::ForEachMacro(
if (macro_info) {
std::string macro_expansion = "#define ";
- macro_expansion.append(mi->first->getName().str());
+ llvm::StringRef macro_identifier = mi->first->getName();
+ macro_expansion.append(macro_identifier.str());
{
if (macro_info->isFunctionLike()) {
@@ -575,7 +578,7 @@ void ClangModulesDeclVendorImpl::ForEachMacro(
}
}
- if (handler(macro_expansion)) {
+ if (handler(macro_identifier, macro_expansion)) {
return;
}
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
index f04d1b07f03d..d820552a2912 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
@@ -90,13 +90,13 @@ public:
/// if module A #defines a macro and module B #undefs it.
///
/// \param[in] handler
- /// A function to call with the text of each #define (including the
- /// #define directive). #undef directives are not included; we simply
- /// elide any corresponding #define. If this function returns true,
- /// we stop the iteration immediately.
- virtual void
- ForEachMacro(const ModuleVector &modules,
- std::function<bool(const std::string &)> handler) = 0;
+ /// A function to call with the identifier of this macro and the text of
+ /// each #define (including the #define directive). #undef directives are
+ /// not included; we simply elide any corresponding #define. If this
+ /// function returns true, we stop the iteration immediately.
+ virtual void ForEachMacro(
+ const ModuleVector &modules,
+ std::function<bool(llvm::StringRef, llvm::StringRef)> handler) = 0;
/// Query whether Clang supports modules for a particular language.
/// LLDB uses this to decide whether to try to find the modules loaded
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index a28b4a7fb42c..9be294750fa0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -417,7 +417,6 @@ void ClangUserExpression::CreateSourceCode(
DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
std::vector<std::string> modules_to_import, bool for_completion) {
- m_filename = m_clang_state->GetNextExprFileName();
std::string prefix = m_expr_prefix;
if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
@@ -477,9 +476,6 @@ CppModuleConfiguration GetModuleConfig(lldb::LanguageType language,
if (!target)
return LogConfigError("No target");
- if (!target->GetEnableImportStdModule())
- return LogConfigError("Importing std module not enabled in settings");
-
StackFrame *frame = exe_ctx.GetFramePtr();
if (!frame)
return LogConfigError("No frame");
@@ -529,8 +525,6 @@ CppModuleConfiguration GetModuleConfig(lldb::LanguageType language,
bool ClangUserExpression::PrepareForParsing(
DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
bool for_completion) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
-
InstallContext(exe_ctx);
if (!SetupPersistentState(diagnostic_manager, exe_ctx))
@@ -551,50 +545,20 @@ bool ClangUserExpression::PrepareForParsing(
SetupDeclVendor(exe_ctx, m_target, diagnostic_manager);
- CppModuleConfiguration module_config = GetModuleConfig(m_language, exe_ctx);
- llvm::ArrayRef<std::string> imported_modules =
- module_config.GetImportedModules();
- m_imported_cpp_modules = !imported_modules.empty();
- m_include_directories = module_config.GetIncludeDirs();
+ m_filename = m_clang_state->GetNextExprFileName();
- LLDB_LOG(log, "List of imported modules in expression: {0}",
- llvm::make_range(imported_modules.begin(), imported_modules.end()));
- LLDB_LOG(log, "List of include directories gathered for modules: {0}",
- llvm::make_range(m_include_directories.begin(),
- m_include_directories.end()));
+ if (m_target->GetImportStdModule() == eImportStdModuleTrue)
+ SetupCppModuleImports(exe_ctx);
- CreateSourceCode(diagnostic_manager, exe_ctx, imported_modules,
+ CreateSourceCode(diagnostic_manager, exe_ctx, m_imported_cpp_modules,
for_completion);
return true;
}
-bool 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));
-
- if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ false))
- return false;
-
- LLDB_LOGF(log, "Parsing the following code:\n%s", m_transformed_text.c_str());
-
- ////////////////////////////////////
- // Set up the target and compiler
- //
-
- Target *target = exe_ctx.GetTargetPtr();
-
- if (!target) {
- diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid target");
- return false;
- }
-
- //////////////////////////
- // Parse the expression
- //
-
+bool ClangUserExpression::TryParse(
+ DiagnosticManager &diagnostic_manager, ExecutionContextScope *exe_scope,
+ ExecutionContext &exe_ctx, lldb_private::ExecutionPolicy execution_policy,
+ bool keep_result_in_memory, bool generate_debug_info) {
m_materializer_up = std::make_unique<Materializer>();
ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
@@ -612,26 +576,16 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
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,
- m_include_directories, m_filename);
+ m_parser = std::make_unique<ClangExpressionParser>(
+ exe_scope, *this, generate_debug_info, m_include_directories, m_filename);
- unsigned num_errors = parser.Parse(diagnostic_manager);
+ unsigned num_errors = m_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) {
if (diagnostic_manager.HasFixIts()) {
- if (parser.RewriteExpression(diagnostic_manager)) {
+ if (m_parser->RewriteExpression(diagnostic_manager)) {
size_t fixed_start;
size_t fixed_end;
m_fixed_text = diagnostic_manager.GetFixedExpression();
@@ -652,7 +606,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
//
{
- Status jit_error = parser.PrepareForExecution(
+ Status jit_error = m_parser->PrepareForExecution(
m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx,
m_can_interpret, execution_policy);
@@ -666,10 +620,91 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
return false;
}
}
+ return true;
+}
+
+void ClangUserExpression::SetupCppModuleImports(ExecutionContext &exe_ctx) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ CppModuleConfiguration module_config = GetModuleConfig(m_language, exe_ctx);
+ m_imported_cpp_modules = module_config.GetImportedModules();
+ m_include_directories = module_config.GetIncludeDirs();
+
+ LLDB_LOG(log, "List of imported modules in expression: {0}",
+ llvm::make_range(m_imported_cpp_modules.begin(),
+ m_imported_cpp_modules.end()));
+ LLDB_LOG(log, "List of include directories gathered for modules: {0}",
+ llvm::make_range(m_include_directories.begin(),
+ m_include_directories.end()));
+}
+
+static bool shouldRetryWithCppModule(Target &target, ExecutionPolicy exe_policy) {
+ // Top-level expression don't yet support importing C++ modules.
+ if (exe_policy == ExecutionPolicy::eExecutionPolicyTopLevel)
+ return false;
+ return target.GetImportStdModule() == eImportStdModuleFallback;
+}
+
+bool 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));
+
+ if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ false))
+ return false;
+
+ LLDB_LOGF(log, "Parsing the following code:\n%s", m_transformed_text.c_str());
+
+ ////////////////////////////////////
+ // Set up the target and compiler
+ //
+
+ Target *target = exe_ctx.GetTargetPtr();
+
+ if (!target) {
+ diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid target");
+ return false;
+ }
+
+ //////////////////////////
+ // Parse the expression
+ //
+
+ Process *process = exe_ctx.GetProcessPtr();
+ ExecutionContextScope *exe_scope = process;
+
+ if (!exe_scope)
+ exe_scope = exe_ctx.GetTargetPtr();
+
+ bool parse_success = TryParse(diagnostic_manager, exe_scope, exe_ctx,
+ execution_policy, keep_result_in_memory,
+ generate_debug_info);
+ // If the expression failed to parse, check if retrying parsing with a loaded
+ // C++ module is possible.
+ if (!parse_success && shouldRetryWithCppModule(*target, execution_policy)) {
+ // Load the loaded C++ modules.
+ SetupCppModuleImports(exe_ctx);
+ // If we did load any modules, then retry parsing.
+ if (!m_imported_cpp_modules.empty()) {
+ // The module imports are injected into the source code wrapper,
+ // so recreate those.
+ CreateSourceCode(diagnostic_manager, exe_ctx, m_imported_cpp_modules,
+ /*for_completion*/ false);
+ // Clear the error diagnostics from the previous parse attempt.
+ diagnostic_manager.Clear();
+ parse_success = TryParse(diagnostic_manager, exe_scope, exe_ctx,
+ execution_policy, keep_result_in_memory,
+ generate_debug_info);
+ }
+ }
+ if (!parse_success)
+ return false;
if (exe_ctx.GetProcessPtr() && execution_policy == eExecutionPolicyTopLevel) {
Status static_init_error =
- parser.RunStaticInitializers(m_execution_unit_sp, exe_ctx);
+ m_parser->RunStaticInitializers(m_execution_unit_sp, exe_ctx);
if (!static_init_error.Success()) {
const char *error_cstr = static_init_error.AsCString();
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
index f734069655ef..b628f6debf66 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
@@ -168,12 +168,23 @@ public:
lldb::ExpressionVariableSP
GetResultAfterDematerialization(ExecutionContextScope *exe_scope) override;
- bool DidImportCxxModules() const { return m_imported_cpp_modules; }
+ /// Returns true iff this expression is using any imported C++ modules.
+ bool DidImportCxxModules() const { return !m_imported_cpp_modules.empty(); }
private:
/// Populate m_in_cplusplus_method and m_in_objectivec_method based on the
/// environment.
+ /// Contains the actual parsing implementation.
+ /// The parameter have the same meaning as in ClangUserExpression::Parse.
+ /// \see ClangUserExpression::Parse
+ bool TryParse(DiagnosticManager &diagnostic_manager,
+ ExecutionContextScope *exe_scope, ExecutionContext &exe_ctx,
+ lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
+ bool generate_debug_info);
+
+ void SetupCppModuleImports(ExecutionContext &exe_ctx);
+
void ScanContext(ExecutionContext &exe_ctx,
lldb_private::Status &err) override;
@@ -219,6 +230,8 @@ private:
ResultDelegate m_result_delegate;
ClangPersistentVariables *m_clang_state;
std::unique_ptr<ClangExpressionSourceCode> m_source_code;
+ /// The parser instance we used to parse the expression.
+ std::unique_ptr<ClangExpressionParser> m_parser;
/// File name used for the expression.
std::string m_filename;
@@ -226,8 +239,9 @@ private:
/// See the comment to `UserExpression::Evaluate` for details.
ValueObject *m_ctx_obj;
- /// True iff this expression explicitly imported C++ modules.
- bool m_imported_cpp_modules = false;
+ /// A list of module names that should be imported when parsing.
+ /// \see CppModuleConfiguration::GetImportedModules
+ std::vector<std::string> m_imported_cpp_modules;
/// True if the expression parser should enforce the presence of a valid class
/// pointer in order to generate the expression as a method.
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
index 25ec982220a0..9788a4e1c183 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -42,12 +42,11 @@ char ClangUtilityFunction::ID;
/// \param[in] name
/// The name of the function, as used in the text.
ClangUtilityFunction::ClangUtilityFunction(ExecutionContextScope &exe_scope,
- const char *text, const char *name)
- : UtilityFunction(exe_scope, text, name) {
- m_function_text.assign(ClangExpressionSourceCode::g_expression_prefix);
- if (text && text[0])
- m_function_text.append(text);
-}
+ std::string text, std::string name)
+ : UtilityFunction(
+ exe_scope,
+ std::string(ClangExpressionSourceCode::g_expression_prefix) + text,
+ std::move(name)) {}
ClangUtilityFunction::~ClangUtilityFunction() {}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
index 1f2dd5fdbecc..7914e1406cd0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
@@ -41,6 +41,34 @@ public:
}
static bool classof(const Expression *obj) { return obj->isA(&ID); }
+ /// Constructor
+ ///
+ /// \param[in] text
+ /// The text of the function. Must be a full translation unit.
+ ///
+ /// \param[in] name
+ /// The name of the function, as used in the text.
+ ClangUtilityFunction(ExecutionContextScope &exe_scope, std::string text,
+ std::string name);
+
+ ~ClangUtilityFunction() override;
+
+ ExpressionTypeSystemHelper *GetTypeSystemHelper() override {
+ return &m_type_system_helper;
+ }
+
+ ClangExpressionDeclMap *DeclMap() { return m_type_system_helper.DeclMap(); }
+
+ void ResetDeclMap() { m_type_system_helper.ResetDeclMap(); }
+
+ void ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory) {
+ m_type_system_helper.ResetDeclMap(exe_ctx, keep_result_in_memory);
+ }
+
+ bool Install(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx) override;
+
+private:
class ClangUtilityFunctionHelper : public ClangExpressionHelper {
public:
ClangUtilityFunctionHelper() {}
@@ -58,7 +86,7 @@ public:
void ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory);
/// Return the object that the parser should allow to access ASTs. May be
- /// NULL if the ASTs do not need to be transformed.
+ /// nullptr if the ASTs do not need to be transformed.
///
/// \param[in] passthrough
/// The ASTConsumer that the returned transformer should send
@@ -71,37 +99,9 @@ public:
private:
std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
};
- /// Constructor
- ///
- /// \param[in] text
- /// The text of the function. Must be a full translation unit.
- ///
- /// \param[in] name
- /// The name of the function, as used in the text.
- ClangUtilityFunction(ExecutionContextScope &exe_scope, const char *text,
- const char *name);
-
- ~ClangUtilityFunction() override;
-
- ExpressionTypeSystemHelper *GetTypeSystemHelper() override {
- return &m_type_system_helper;
- }
- ClangExpressionDeclMap *DeclMap() { return m_type_system_helper.DeclMap(); }
-
- void ResetDeclMap() { m_type_system_helper.ResetDeclMap(); }
-
- void ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory) {
- m_type_system_helper.ResetDeclMap(exe_ctx, keep_result_in_memory);
- }
-
- bool Install(DiagnosticManager &diagnostic_manager,
- ExecutionContext &exe_ctx) override;
-
-private:
- ClangUtilityFunctionHelper m_type_system_helper; ///< The map to use when
- ///parsing and materializing
- ///the expression.
+ /// The map to use when parsing and materializing the expression.
+ ClangUtilityFunctionHelper m_type_system_helper;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
index f1272c67d20f..ffab16b1682b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
@@ -38,9 +38,11 @@ bool CppModuleConfiguration::analyzeFile(const FileSpec &f) {
// Check for /c++/vX/ that is used by libc++.
static llvm::Regex libcpp_regex(R"regex(/c[+][+]/v[0-9]/)regex");
- if (libcpp_regex.match(f.GetPath())) {
- // Strip away libc++'s /experimental directory if there is one.
- posix_dir.consume_back("/experimental");
+ // If the path is in the libc++ include directory use it as the found libc++
+ // path. Ignore subdirectories such as /c++/v1/experimental as those don't
+ // need to be specified in the header search.
+ if (libcpp_regex.match(f.GetPath()) &&
+ parent_path(posix_dir, Style::posix).endswith("c++")) {
return m_std_inc.TrySet(posix_dir);
}
@@ -55,9 +57,38 @@ bool CppModuleConfiguration::analyzeFile(const FileSpec &f) {
return true;
}
+/// Utility function for just appending two paths.
+static std::string MakePath(llvm::StringRef lhs, llvm::StringRef rhs) {
+ llvm::SmallString<256> result(lhs);
+ llvm::sys::path::append(result, rhs);
+ return std::string(result);
+}
+
bool CppModuleConfiguration::hasValidConfig() {
- // We all these include directories to have a valid usable configuration.
- return m_c_inc.Valid() && m_std_inc.Valid();
+ // We need to have a C and C++ include dir for a valid configuration.
+ if (!m_c_inc.Valid() || !m_std_inc.Valid())
+ return false;
+
+ // Do some basic sanity checks on the directories that we don't activate
+ // the module when it's clear that it's not usable.
+ const std::vector<std::string> files_to_check = {
+ // * Check that the C library contains at least one random C standard
+ // library header.
+ MakePath(m_c_inc.Get(), "stdio.h"),
+ // * Without a libc++ modulemap file we can't have a 'std' module that
+ // could be imported.
+ MakePath(m_std_inc.Get(), "module.modulemap"),
+ // * Check for a random libc++ header (vector in this case) that has to
+ // exist in a working libc++ setup.
+ MakePath(m_std_inc.Get(), "vector"),
+ };
+
+ for (llvm::StringRef file_to_check : files_to_check) {
+ if (!FileSystem::Instance().Exists(file_to_check))
+ return false;
+ }
+
+ return true;
}
CppModuleConfiguration::CppModuleConfiguration(
@@ -76,7 +107,8 @@ CppModuleConfiguration::CppModuleConfiguration(
m_resource_inc = std::string(resource_dir.str());
// This order matches the way Clang orders these directories.
- m_include_dirs = {m_std_inc.Get(), m_resource_inc, m_c_inc.Get()};
+ m_include_dirs = {m_std_inc.Get().str(), m_resource_inc,
+ m_c_inc.Get().str()};
m_imported_modules = {"std"};
}
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
index 235ac2bd090c..b984db43fa6d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
@@ -32,7 +32,7 @@ class CppModuleConfiguration {
/// the path was already set.
LLVM_NODISCARD bool TrySet(llvm::StringRef path);
/// Return the path if there is one.
- std::string Get() const {
+ llvm::StringRef Get() const {
assert(m_valid && "Called Get() on an invalid SetOncePath?");
return m_path;
}
@@ -57,9 +57,6 @@ class CppModuleConfiguration {
public:
/// Creates a configuration by analyzing the given list of used source files.
- ///
- /// Currently only looks at the used paths and doesn't actually access the
- /// files on the disk.
explicit CppModuleConfiguration(const FileSpecList &support_files);
/// Creates an empty and invalid configuration.
CppModuleConfiguration() {}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp
index 2f8cf1846ee7..f953e860969c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp
@@ -22,6 +22,7 @@ CxxModuleHandler::CxxModuleHandler(ASTImporter &importer, ASTContext *target)
std::initializer_list<const char *> supported_names = {
// containers
+ "array",
"deque",
"forward_list",
"list",
@@ -34,6 +35,7 @@ CxxModuleHandler::CxxModuleHandler(ASTImporter &importer, ASTContext *target)
"weak_ptr",
// utility
"allocator",
+ "pair",
};
m_supported_templates.insert(supported_names.begin(), supported_names.end());
}
@@ -180,21 +182,21 @@ llvm::Optional<Decl *> CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) {
// If we don't have a template to instiantiate, then there is nothing to do.
auto td = dyn_cast<ClassTemplateSpecializationDecl>(d);
if (!td)
- return {};
+ return llvm::None;
// We only care about templates in the std namespace.
if (!td->getDeclContext()->isStdNamespace())
- return {};
+ return llvm::None;
// We have a list of supported template names.
- if (m_supported_templates.find(td->getName()) == m_supported_templates.end())
- return {};
+ if (!m_supported_templates.contains(td->getName()))
+ return llvm::None;
// Early check if we even support instantiating this template. We do this
// before we import anything into the target AST.
auto &foreign_args = td->getTemplateInstantiationArgs();
if (!templateArgsAreSupported(foreign_args.asArray()))
- return {};
+ return llvm::None;
// Find the local DeclContext that corresponds to the DeclContext of our
// decl we want to import.
@@ -205,7 +207,7 @@ llvm::Optional<Decl *> CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) {
"Got error while searching equal local DeclContext for decl "
"'{1}':\n{0}",
td->getName());
- return {};
+ return llvm::None;
}
// Look up the template in our local context.
@@ -218,7 +220,7 @@ llvm::Optional<Decl *> CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) {
break;
}
if (!new_class_template)
- return {};
+ return llvm::None;
// Import the foreign template arguments.
llvm::SmallVector<TemplateArgument, 4> imported_args;
@@ -230,7 +232,7 @@ llvm::Optional<Decl *> CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) {
llvm::Expected<QualType> type = m_importer->Import(arg.getAsType());
if (!type) {
LLDB_LOG_ERROR(log, type.takeError(), "Couldn't import type: {0}");
- return {};
+ return llvm::None;
}
imported_args.push_back(TemplateArgument(*type));
break;
@@ -241,7 +243,7 @@ llvm::Optional<Decl *> CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) {
m_importer->Import(arg.getIntegralType());
if (!type) {
LLDB_LOG_ERROR(log, type.takeError(), "Couldn't import type: {0}");
- return {};
+ return llvm::None;
}
imported_args.push_back(
TemplateArgument(d->getASTContext(), integral, *type));
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
index b92f00ec2b63..a6e36d81b950 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp
@@ -48,29 +48,27 @@ ClangDynamicCheckerFunctions::~ClangDynamicCheckerFunctions() = default;
bool ClangDynamicCheckerFunctions::Install(
DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) {
- Status error;
- m_valid_pointer_check.reset(
- exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(
- g_valid_pointer_check_text, lldb::eLanguageTypeC,
- VALID_POINTER_CHECK_NAME, error));
- if (error.Fail())
+ auto utility_fn_or_error = exe_ctx.GetTargetRef().CreateUtilityFunction(
+ g_valid_pointer_check_text, VALID_POINTER_CHECK_NAME,
+ lldb::eLanguageTypeC, exe_ctx);
+ if (!utility_fn_or_error) {
+ llvm::consumeError(utility_fn_or_error.takeError());
return false;
+ }
+ m_valid_pointer_check = std::move(*utility_fn_or_error);
- if (!m_valid_pointer_check->Install(diagnostic_manager, exe_ctx))
- return false;
-
- Process *process = exe_ctx.GetProcessPtr();
-
- if (process) {
+ if (Process *process = exe_ctx.GetProcessPtr()) {
ObjCLanguageRuntime *objc_language_runtime =
ObjCLanguageRuntime::Get(*process);
if (objc_language_runtime) {
- m_objc_object_check.reset(objc_language_runtime->CreateObjectChecker(
- VALID_OBJC_OBJECT_CHECK_NAME));
-
- if (!m_objc_object_check->Install(diagnostic_manager, exe_ctx))
+ auto utility_fn_or_error = objc_language_runtime->CreateObjectChecker(
+ VALID_OBJC_OBJECT_CHECK_NAME, exe_ctx);
+ if (!utility_fn_or_error) {
+ llvm::consumeError(utility_fn_or_error.takeError());
return false;
+ }
+ m_objc_object_check = std::move(*utility_fn_or_error);
}
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index 8511e554509a..b35bf07034bd 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -305,9 +305,7 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
}
lldb::TargetSP target_sp(m_execution_unit.GetTarget());
- lldb_private::ExecutionContext exe_ctx(target_sp, true);
- llvm::Optional<uint64_t> bit_size =
- m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope());
+ llvm::Optional<uint64_t> bit_size = m_result_type.GetBitSize(target_sp.get());
if (!bit_size) {
lldb_private::StreamString type_desc_stream;
m_result_type.DumpTypeDescription(&type_desc_stream);
@@ -330,7 +328,8 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
m_result_name = lldb_private::ConstString("$RESULT_NAME");
LLDB_LOG(log, "Creating a new result global: \"{0}\" with size {1}",
- m_result_name, m_result_type.GetByteSize(nullptr).getValueOr(0));
+ m_result_name,
+ m_result_type.GetByteSize(target_sp.get()).getValueOr(0));
// Construct a new result global and set up its metadata
@@ -1242,10 +1241,12 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
value_type = global_variable->getType();
}
- llvm::Optional<uint64_t> value_size = compiler_type.GetByteSize(nullptr);
+ auto *target = m_execution_unit.GetTarget().get();
+ llvm::Optional<uint64_t> value_size = compiler_type.GetByteSize(target);
if (!value_size)
return false;
- llvm::Optional<size_t> opt_alignment = compiler_type.GetTypeBitAlign(nullptr);
+ llvm::Optional<size_t> opt_alignment =
+ compiler_type.GetTypeBitAlign(target);
if (!opt_alignment)
return false;
lldb::offset_t value_alignment = (*opt_alignment + 7ull) / 8ull;
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h
index b7b6640c4810..4fe727460fdb 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ModuleDependencyCollector.h
@@ -18,7 +18,7 @@ class ModuleDependencyCollectorAdaptor
: public clang::ModuleDependencyCollector {
public:
ModuleDependencyCollectorAdaptor(
- std::shared_ptr<llvm::FileCollector> file_collector)
+ std::shared_ptr<llvm::FileCollectorBase> file_collector)
: clang::ModuleDependencyCollector(""), m_file_collector(file_collector) {
}
@@ -33,7 +33,7 @@ public:
void writeFileMap() override {}
private:
- std::shared_ptr<llvm::FileCollector> m_file_collector;
+ std::shared_ptr<llvm::FileCollectorBase> m_file_collector;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
index c1f88889f1dc..829afa5ffcec 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
@@ -78,7 +78,8 @@ clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
clang::FunctionDecl *func_decl = FunctionDecl::Create(
ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type,
nullptr, SC_Extern, isInlineSpecified, hasWrittenPrototype,
- isConstexprSpecified ? CSK_constexpr : CSK_unspecified);
+ isConstexprSpecified ? ConstexprSpecKind::Constexpr
+ : ConstexprSpecKind::Unspecified);
// We have to do more than just synthesize the FunctionDecl. We have to
// synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do
diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
index 72d28c347457..99784bd3dbd1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
@@ -114,7 +114,7 @@ InstrumentationRuntimeMainThreadChecker::RetrieveReportData(
std::string className = "";
std::string selector = "";
if (apiName.substr(0, 2) == "-[") {
- size_t spacePos = apiName.find(" ");
+ size_t spacePos = apiName.find(' ');
if (spacePos != std::string::npos) {
className = apiName.substr(2, spacePos - 2);
selector = apiName.substr(spacePos + 1, apiName.length() - spacePos - 2);
diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp
index 50f0faefa0f4..a2954f556b10 100644
--- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp
@@ -809,7 +809,9 @@ bool InstrumentationRuntimeTSan::NotifyBreakpointHit(
StructuredData::ObjectSP report =
instance->RetrieveReportData(context->exe_ctx_ref);
- std::string stop_reason_description;
+ std::string stop_reason_description =
+ "unknown thread sanitizer fault (unable to extract thread sanitizer "
+ "report)";
if (report) {
std::string issue_description = instance->FormatDescription(report);
report->GetAsDictionary()->AddStringItem("description", issue_description);
diff --git a/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp b/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
index 74d65b3caaf0..33dfc7b3281e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
@@ -293,8 +293,8 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
jit_descriptor<ptr_t> jit_desc;
const size_t jit_desc_size = sizeof(jit_desc);
Status error;
- size_t bytes_read = m_process->DoReadMemory(m_jit_descriptor_addr, &jit_desc,
- jit_desc_size, error);
+ size_t bytes_read = m_process->ReadMemory(m_jit_descriptor_addr, &jit_desc,
+ jit_desc_size, error);
if (bytes_read != jit_desc_size || !error.Success()) {
LLDB_LOGF(log, "JITLoaderGDB::%s failed to read JIT descriptor",
__FUNCTION__);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
index 42f6bd9ffb7b..35788a6445c2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
@@ -50,11 +50,7 @@ public:
}
TypeSystemClang *clang_ast_context =
- llvm::dyn_cast<TypeSystemClang>(&type_system_or_err.get());
-
- if (!clang_ast_context) {
- return;
- }
+ llvm::cast<TypeSystemClang>(block_pointer_type.GetTypeSystem());
std::shared_ptr<ClangASTImporter> clang_ast_importer;
auto *state = target_sp->GetPersistentExpressionStateForLanguage(
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 08e43ae6b3e8..d844498fd8a3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -601,8 +601,7 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
ConstString("^std::__[[:alnum:]]+::atomic<.+>$"), stl_synth_flags, true);
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpression(
- llvm::StringRef("^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$")),
+ RegularExpression("^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$"),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
@@ -823,32 +822,32 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
false);
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$")),
+ RegularExpression("^std::vector<.+>(( )?&)?$"),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$")),
+ RegularExpression("^std::map<.+> >(( )?&)?$"),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpression(llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$")),
+ RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
stl_summary_flags.SetDontShowChildren(false);
stl_summary_flags.SetSkipPointers(true);
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$")),
+ RegularExpression("^std::vector<.+>(( )?&)?$"),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$")),
+ RegularExpression("^std::map<.+> >(( )?&)?$"),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpression(llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$")),
+ RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
@@ -1135,6 +1134,15 @@ CPlusPlusLanguage::GetHardcodedSynthetics() {
return g_formatters;
}
+bool CPlusPlusLanguage::IsNilReference(ValueObject &valobj) {
+ if (!Language::LanguageIsCPlusPlus(valobj.GetObjectRuntimeLanguage()) ||
+ !valobj.IsPointerType())
+ return false;
+ bool canReadValue = true;
+ bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0;
+ return canReadValue && isZero;
+}
+
bool CPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const {
const auto suffixes = {".cpp", ".cxx", ".c++", ".cc", ".c",
".h", ".hh", ".hpp", ".hxx", ".h++"};
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
index 89dea08a2c53..e2b5d2918753 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -88,6 +88,10 @@ public:
HardcodedFormatters::HardcodedSyntheticFinder
GetHardcodedSynthetics() override;
+ bool IsNilReference(ValueObject &valobj) override;
+
+ llvm::StringRef GetNilReferenceSummaryString() override { return "nullptr"; }
+
bool IsSourceFile(llvm::StringRef file_path) const override;
const Highlighter *GetHighlighter() const override { return &m_highlighter; }
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 84dd09a47d8a..2b16ebe79daf 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -692,7 +692,7 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(
// std::wstring::size() is measured in 'characters', not bytes
TypeSystemClang *ast_context =
- TypeSystemClang::GetScratch(*valobj.GetTargetSP());
+ ScratchTypeSystemClang::GetForTarget(*valobj.GetTargetSP());
if (!ast_context)
return false;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp
index aaf578c6f728..fe6eeea54e4d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp
@@ -168,7 +168,7 @@ void ClangHighlighter::Highlight(const HighlightStyle &options,
clang::SourceManager SM(diags, file_mgr);
auto buf = llvm::MemoryBuffer::getMemBuffer(full_source);
- FileID FID = SM.createFileID(clang::SourceManager::Unowned, buf.get());
+ FileID FID = SM.createFileID(buf->getMemBufferRef());
// Let's just enable the latest ObjC and C++ which should get most tokens
// right.
@@ -178,7 +178,7 @@ void ClangHighlighter::Highlight(const HighlightStyle &options,
Opts.CPlusPlus17 = true;
Opts.LineComment = true;
- Lexer lex(FID, buf.get(), SM, Opts);
+ Lexer lex(FID, buf->getMemBufferRef(), SM, Opts);
// The lexer should keep whitespace around.
lex.SetKeepWhitespaceMode(true);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
index 648fc4adf24f..d871d3470e70 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
@@ -72,6 +72,9 @@ bool lldb_private::formatters::NSBundleSummaryProvider(
valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID),
true));
+ if (!text)
+ return false;
+
StreamString summary_stream;
bool was_nsstring_ok =
NSStringSummaryProvider(*text, summary_stream, options);
@@ -117,6 +120,10 @@ bool lldb_private::formatters::NSTimeZoneSummaryProvider(
uint64_t offset = ptr_size;
ValueObjectSP text(valobj.GetSyntheticChildAtOffset(
offset, valobj.GetCompilerType(), true));
+
+ if (!text)
+ return false;
+
StreamString summary_stream;
bool was_nsstring_ok =
NSStringSummaryProvider(*text, summary_stream, options);
@@ -162,6 +169,10 @@ bool lldb_private::formatters::NSNotificationSummaryProvider(
uint64_t offset = ptr_size;
ValueObjectSP text(valobj.GetSyntheticChildAtOffset(
offset, valobj.GetCompilerType(), true));
+
+ if (!text)
+ return false;
+
StreamString summary_stream;
bool was_nsstring_ok =
NSStringSummaryProvider(*text, summary_stream, options);
@@ -1024,7 +1035,7 @@ bool lldb_private::formatters::ObjCBOOLSummaryProvider(
if (!real_guy_sp)
return false;
}
- uint8_t value = (real_guy_sp->GetValueAsUnsigned(0) & 0xFF);
+ int8_t value = (real_guy_sp->GetValueAsSigned(0) & 0xFF);
switch (value) {
case 0:
stream.Printf("NO");
@@ -1033,7 +1044,7 @@ bool lldb_private::formatters::ObjCBOOLSummaryProvider(
stream.Printf("YES");
break;
default:
- stream.Printf("%u", value);
+ stream.Printf("%d", value);
break;
}
return true;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
index ac2f45b8354f..efc80cc75557 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
@@ -25,21 +25,12 @@ bool lldb_private::formatters::CMTimeSummaryProvider(
if (!type.IsValid())
return false;
- auto type_system_or_err =
- valobj.GetExecutionContextRef()
- .GetTargetSP()
- ->GetScratchTypeSystemForLanguage(lldb::eLanguageTypeC);
- if (auto err = type_system_or_err.takeError()) {
- LLDB_LOG_ERROR(
- lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS),
- std::move(err), "Failed to get scratch type system");
- return false;
- }
+ TypeSystem *type_system = type.GetTypeSystem();
// fetch children by offset to compensate for potential lack of debug info
- auto int64_ty = type_system_or_err->GetBuiltinTypeForEncodingAndBitSize(
- eEncodingSint, 64);
- auto int32_ty = type_system_or_err->GetBuiltinTypeForEncodingAndBitSize(
- eEncodingSint, 32);
+ auto int64_ty =
+ type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 64);
+ auto int32_ty =
+ type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32);
auto value_sp(valobj.GetSyntheticChildAtOffset(0, int64_ty, true));
auto timescale_sp(valobj.GetSyntheticChildAtOffset(8, int32_ty, true));
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSArray.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSArray.cpp
index 8d648d8a0861..b0398dd19c02 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSArray.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSArray.cpp
@@ -96,7 +96,7 @@ private:
D32 *m_data_32;
D64 *m_data_64;
};
-
+
namespace Foundation1010 {
namespace {
struct DataDescriptor_32 {
@@ -107,7 +107,7 @@ namespace Foundation1010 {
uint32_t _priv2;
uint32_t _data;
};
-
+
struct DataDescriptor_64 {
uint64_t _used;
uint64_t _offset;
@@ -117,11 +117,11 @@ namespace Foundation1010 {
uint64_t _data;
};
}
-
+
using NSArrayMSyntheticFrontEnd =
GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
}
-
+
namespace Foundation1428 {
namespace {
struct DataDescriptor_32 {
@@ -130,7 +130,7 @@ namespace Foundation1428 {
uint32_t _size;
uint32_t _data;
};
-
+
struct DataDescriptor_64 {
uint64_t _used;
uint64_t _offset;
@@ -138,11 +138,11 @@ namespace Foundation1428 {
uint64_t _data;
};
}
-
+
using NSArrayMSyntheticFrontEnd =
GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
}
-
+
namespace Foundation1437 {
template <typename PtrType>
struct DataDescriptor {
@@ -154,11 +154,11 @@ namespace Foundation1437 {
uint32_t _muts;
uint32_t _used;
};
-
+
using NSArrayMSyntheticFrontEnd =
GenericNSArrayMSyntheticFrontEnd<
DataDescriptor<uint32_t>, DataDescriptor<uint64_t>>;
-
+
template <typename DD>
uint64_t
__NSArrayMSize_Impl(lldb_private::Process &process,
@@ -173,7 +173,7 @@ namespace Foundation1437 {
}
return descriptor._used;
}
-
+
uint64_t
__NSArrayMSize(lldb_private::Process &process, lldb::addr_t valobj_addr,
Status &error) {
@@ -227,23 +227,23 @@ public:
private:
ExecutionContextRef m_exe_ctx_ref;
uint8_t m_ptr_size;
-
+
D32 *m_data_32;
D64 *m_data_64;
CompilerType m_id_type;
};
-
+
namespace Foundation1300 {
struct IDD32 {
uint32_t used;
uint32_t list;
};
-
+
struct IDD64 {
uint64_t used;
uint64_t list;
};
-
+
using NSArrayISyntheticFrontEnd =
GenericNSArrayISyntheticFrontEnd<IDD32, IDD64, true>;
}
@@ -258,18 +258,18 @@ namespace Foundation1436 {
uint32_t used;
uint32_t list; // in Inline cases, this is the first element
};
-
+
struct IDD64 {
uint64_t used;
uint64_t list; // in Inline cases, this is the first element
};
-
+
using NSArrayI_TransferSyntheticFrontEnd =
GenericNSArrayISyntheticFrontEnd<IDD32, IDD64, false>;
using NSArrayISyntheticFrontEnd =
GenericNSArrayISyntheticFrontEnd<IDD32, IDD64, true>;
-
+
using NSFrozenArrayMSyntheticFrontEnd =
Foundation1437::NSArrayMSyntheticFrontEnd;
@@ -441,7 +441,7 @@ lldb_private::formatters::NSArrayMSyntheticFrontEndBase::NSArrayMSyntheticFrontE
: SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
m_id_type() {
if (valobj_sp) {
- auto *clang_ast_context = TypeSystemClang::GetScratch(
+ auto *clang_ast_context = ScratchTypeSystemClang::GetForTarget(
*valobj_sp->GetExecutionContextRef().GetTargetSP());
if (clang_ast_context)
m_id_type = CompilerType(
@@ -589,7 +589,7 @@ lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>::
if (valobj_sp) {
CompilerType type = valobj_sp->GetCompilerType();
if (type) {
- auto *clang_ast_context = TypeSystemClang::GetScratch(
+ auto *clang_ast_context = ScratchTypeSystemClang::GetForTarget(
*valobj_sp->GetExecutionContextRef().GetTargetSP());
if (clang_ast_context)
m_id_type = clang_ast_context->GetType(
@@ -758,7 +758,7 @@ lldb_private::formatters::NSArray1SyntheticFrontEnd::GetChildAtIndex(
if (idx == 0) {
auto *clang_ast_context =
- TypeSystemClang::GetScratch(*m_backend.GetTargetSP());
+ ScratchTypeSystemClang::GetForTarget(*m_backend.GetTargetSP());
if (clang_ast_context) {
CompilerType id_type(
clang_ast_context->GetBasicType(lldb::eBasicTypeObjCID));
@@ -820,11 +820,9 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator(
return (new Foundation1436::NSArrayISyntheticFrontEnd(valobj_sp));
if (runtime->GetFoundationVersion() >= 1430)
return (new Foundation1430::NSArrayISyntheticFrontEnd(valobj_sp));
- else
- return (new Foundation1300::NSArrayISyntheticFrontEnd(valobj_sp));
+ return (new Foundation1300::NSArrayISyntheticFrontEnd(valobj_sp));
} else if (class_name == g_NSArrayI_Transfer) {
return (new Foundation1436::NSArrayI_TransferSyntheticFrontEnd(valobj_sp));
- } else if (class_name == g_NSArray0) {
} else if (class_name == g_NSFrozenArrayM) {
return (new Foundation1436::NSFrozenArrayMSyntheticFrontEnd(valobj_sp));
} else if (class_name == g_NSArray0) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
index 3dc07678f92f..afb9c6951f55 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -66,7 +66,8 @@ NSDictionary_Additionals::GetAdditionalSynthetics() {
static CompilerType GetLLDBNSPairType(TargetSP target_sp) {
CompilerType compiler_type;
- TypeSystemClang *target_ast_context = TypeSystemClang::GetScratch(*target_sp);
+ TypeSystemClang *target_ast_context =
+ ScratchTypeSystemClang::GetForTarget(*target_sp);
if (target_ast_context) {
ConstString g___lldb_autogen_nspair("__lldb_autogen_nspair");
@@ -388,7 +389,7 @@ bool lldb_private::formatters::NSDictionarySummaryProvider(
return false;
ObjCLanguageRuntime::ClassDescriptorSP descriptor(
- runtime->GetClassDescriptor(valobj));
+ runtime->GetNonKVOClassDescriptor(valobj));
if (!descriptor || !descriptor->IsValid())
return false;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSError.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSError.cpp
index aa1103cb342c..4ffa072f9f53 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSError.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSError.cpp
@@ -87,7 +87,7 @@ bool lldb_private::formatters::NSError_SummaryProvider(
ValueObjectSP domain_str_sp = ValueObject::CreateValueObjectFromData(
"domain_str", isw.GetAsData(process_sp->GetByteOrder()),
valobj.GetExecutionContextRef(),
- TypeSystemClang::GetScratch(process_sp->GetTarget())
+ ScratchTypeSystemClang::GetForTarget(process_sp->GetTarget())
->GetBasicType(lldb::eBasicTypeVoid)
.GetPointerType());
@@ -156,7 +156,7 @@ public:
m_child_sp = CreateValueObjectFromData(
"_userInfo", isw.GetAsData(process_sp->GetByteOrder()),
m_backend.GetExecutionContextRef(),
- TypeSystemClang::GetScratch(process_sp->GetTarget())
+ ScratchTypeSystemClang::GetForTarget(process_sp->GetTarget())
->GetBasicType(lldb::eBasicTypeObjCID));
return false;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSException.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSException.cpp
index c6bae5e1c008..7360abb8fdd2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSException.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSException.cpp
@@ -69,7 +69,8 @@ static bool ExtractFields(ValueObject &valobj, ValueObjectSP *name_sp,
InferiorSizedWord userinfo_isw(userinfo, *process_sp);
InferiorSizedWord reserved_isw(reserved, *process_sp);
- auto *clang_ast_context = TypeSystemClang::GetScratch(process_sp->GetTarget());
+ auto *clang_ast_context =
+ ScratchTypeSystemClang::GetForTarget(process_sp->GetTarget());
if (!clang_ast_context)
return false;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
index d962f39611b6..a15b0f64954a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
@@ -53,7 +53,7 @@ public:
if (!type_system)
return false;
- TypeSystemClang *ast = TypeSystemClang::GetScratch(
+ TypeSystemClang *ast = ScratchTypeSystemClang::GetForTarget(
*m_backend.GetExecutionContextRef().GetTargetSP());
if (!ast)
return false;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp
index b9d0d73cbc2e..85922992eb2b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp
@@ -34,7 +34,7 @@ NSString_Additionals::GetAdditionalSummaries() {
static CompilerType GetNSPathStore2Type(Target &target) {
static ConstString g_type_name("__lldb_autogen_nspathstore2");
- TypeSystemClang *ast_ctx = TypeSystemClang::GetScratch(target);
+ TypeSystemClang *ast_ctx = ScratchTypeSystemClang::GetForTarget(target);
if (!ast_ctx)
return CompilerType();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
index bed62a5c447a..02c15e86046b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -119,6 +119,8 @@ public:
bool IsNilReference(ValueObject &valobj) override;
+ llvm::StringRef GetNilReferenceSummaryString() override { return "nil"; }
+
bool IsSourceFile(llvm::StringRef file_path) const override;
const Highlighter *GetHighlighter() const override { return &m_highlighter; }
diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h b/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
index 4b3d23653347..233fd5c00a7a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
@@ -27,6 +27,8 @@ public:
return lldb::eLanguageTypeObjC_plus_plus;
}
+ llvm::StringRef GetNilReferenceSummaryString() override { return "nil"; }
+
bool IsSourceFile(llvm::StringRef file_path) const override;
const Highlighter *GetHighlighter() const override { return &m_highlighter; }
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
index 8aa803a8553e..24ab9cc5f238 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
@@ -37,9 +37,6 @@ static ConstString g_this = ConstString("this");
char CPPLanguageRuntime::ID = 0;
-// Destructor
-CPPLanguageRuntime::~CPPLanguageRuntime() {}
-
CPPLanguageRuntime::CPPLanguageRuntime(Process *process)
: LanguageRuntime(process) {}
@@ -102,9 +99,7 @@ line_entry_helper(Target &target, const SymbolContext &sc, Symbol *symbol,
CPPLanguageRuntime::LibCppStdFunctionCallableInfo
CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo(
lldb::ValueObjectSP &valobj_sp) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat,
- "CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo");
+ LLDB_SCOPED_TIMER();
LibCppStdFunctionCallableInfo optional_info;
@@ -154,6 +149,9 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo(
member__f_ = sub_member__f_;
}
+ if (!member__f_)
+ return optional_info;
+
lldb::addr_t member__f_pointer_value = member__f_->GetValueAsUnsigned(0);
optional_info.member__f_pointer_value = member__f_pointer_value;
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
index 5b00590e6301..3f5b99351872 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
@@ -40,8 +40,6 @@ public:
LibCppStdFunctionCallableInfo
FindLibCppStdFunctionCallableInfo(lldb::ValueObjectSP &valobj_sp);
- ~CPPLanguageRuntime() override;
-
static char ID;
bool isA(const void *ClassID) const override {
@@ -89,9 +87,6 @@ private:
llvm::StringMap<CPPLanguageRuntime::LibCppStdFunctionCallableInfo>;
OperatorStringToCallableInfoMap CallableLookupCache;
-
- CPPLanguageRuntime(const CPPLanguageRuntime &) = delete;
- const CPPLanguageRuntime &operator=(const CPPLanguageRuntime &) = delete;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 3ab32641d9c1..6ea9751f563a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -536,7 +536,7 @@ ValueObjectSP ItaniumABILanguageRuntime::GetExceptionObjectForThread(
return {};
TypeSystemClang *clang_ast_context =
- TypeSystemClang::GetScratch(m_process->GetTarget());
+ ScratchTypeSystemClang::GetForTarget(m_process->GetTarget());
if (!clang_ast_context)
return {};
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index 22ea83a57beb..973a5570c06e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -122,7 +122,8 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value,
}
} else {
// If it is not a pointer, see if we can make it into a pointer.
- TypeSystemClang *ast_context = TypeSystemClang::GetScratch(*target);
+ TypeSystemClang *ast_context =
+ ScratchTypeSystemClang::GetForTarget(*target);
if (!ast_context)
return false;
@@ -137,7 +138,7 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value,
arg_value_list.PushValue(value);
// This is the return value:
- TypeSystemClang *ast_context = TypeSystemClang::GetScratch(*target);
+ TypeSystemClang *ast_context = ScratchTypeSystemClang::GetForTarget(*target);
if (!ast_context)
return false;
@@ -376,12 +377,7 @@ AppleObjCRuntime::GetObjCVersion(Process *process, ModuleSP &objc_module_sp) {
llvm::Triple::VendorType::Apple)
return ObjCRuntimeVersions::eObjC_VersionUnknown;
- const ModuleList &target_modules = target.GetImages();
- 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++) {
- ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked(i);
+ for (ModuleSP module_sp : target.GetImages().Modules()) {
// One tricky bit here is that we might get called as part of the initial
// module loading, but before all the pre-run libraries get winnowed from
// the module list. So there might actually be an old and incorrect ObjC
@@ -525,7 +521,7 @@ ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException(
return FailExceptionParsing("Failed to get synthetic value.");
TypeSystemClang *clang_ast_context =
- TypeSystemClang::GetScratch(*exception_sp->GetTargetSP());
+ ScratchTypeSystemClang::GetForTarget(*exception_sp->GetTargetSP());
if (!clang_ast_context)
return FailExceptionParsing("Failed to get scratch AST.");
CompilerType objc_id =
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index 8202686597ae..b37e5a9a7bf9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -122,58 +122,60 @@ struct BufStruct {
char contents[2048];
};
-UtilityFunction *AppleObjCRuntimeV1::CreateObjectChecker(const char *name) {
+llvm::Expected<std::unique_ptr<UtilityFunction>>
+AppleObjCRuntimeV1::CreateObjectChecker(std::string name,
+ ExecutionContext &exe_ctx) {
std::unique_ptr<BufStruct> buf(new BufStruct);
- int strformatsize = snprintf(&buf->contents[0], sizeof(buf->contents),
- "struct __objc_class "
- " \n"
- "{ "
- " \n"
- " struct __objc_class *isa; "
- " \n"
- " struct __objc_class *super_class; "
- " \n"
- " const char *name; "
- " \n"
- " // rest of struct elided because unused "
- " \n"
- "}; "
- " \n"
- " "
- " \n"
- "struct __objc_object "
- " \n"
- "{ "
- " \n"
- " struct __objc_class *isa; "
- " \n"
- "}; "
- " \n"
- " "
- " \n"
- "extern \"C\" void "
- " \n"
- "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) "
- " \n"
- "{ "
- " \n"
- " struct __objc_object *obj = (struct "
- "__objc_object*)$__lldb_arg_obj; \n"
- " if ($__lldb_arg_obj == (void *)0) "
- " \n"
- " return; // nil is ok "
- " (int)strlen(obj->isa->name); "
- " \n"
- "} "
- " \n",
- name);
+ int strformatsize =
+ snprintf(&buf->contents[0], sizeof(buf->contents),
+ "struct __objc_class "
+ " \n"
+ "{ "
+ " \n"
+ " struct __objc_class *isa; "
+ " \n"
+ " struct __objc_class *super_class; "
+ " \n"
+ " const char *name; "
+ " \n"
+ " // rest of struct elided because unused "
+ " \n"
+ "}; "
+ " \n"
+ " "
+ " \n"
+ "struct __objc_object "
+ " \n"
+ "{ "
+ " \n"
+ " struct __objc_class *isa; "
+ " \n"
+ "}; "
+ " \n"
+ " "
+ " \n"
+ "extern \"C\" void "
+ " \n"
+ "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) "
+ " \n"
+ "{ "
+ " \n"
+ " struct __objc_object *obj = (struct "
+ "__objc_object*)$__lldb_arg_obj; \n"
+ " if ($__lldb_arg_obj == (void *)0) "
+ " \n"
+ " return; // nil is ok "
+ " (int)strlen(obj->isa->name); "
+ " \n"
+ "} "
+ " \n",
+ name.c_str());
assert(strformatsize < (int)sizeof(buf->contents));
(void)strformatsize;
- Status error;
- return GetTargetRef().GetUtilityFunctionForLanguage(
- buf->contents, eLanguageTypeObjC, name, error);
+ return GetTargetRef().CreateUtilityFunction(buf->contents, std::move(name),
+ eLanguageTypeC, exe_ctx);
}
AppleObjCRuntimeV1::ClassDescriptorV1::ClassDescriptorV1(
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
index d8725d0f57ce..4eb7d979394b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
@@ -97,7 +97,8 @@ public:
Address &address,
Value::ValueType &value_type) override;
- UtilityFunction *CreateObjectChecker(const char *) override;
+ llvm::Expected<std::unique_ptr<UtilityFunction>>
+ CreateObjectChecker(std::string, ExecutionContext &exe_ctx) override;
// PluginInterface protocol
ConstString GetPluginName() override;
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index ac9a09394021..ee84ccd869fc 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -407,7 +407,7 @@ ExtractRuntimeGlobalSymbol(Process *process, ConstString name,
}
}
-static void RegisterObjCExceptionRecognizer();
+static void RegisterObjCExceptionRecognizer(Process *process);
AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process,
const ModuleSP &objc_module_sp)
@@ -429,7 +429,7 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process,
m_has_object_getClass =
(objc_module_sp->FindFirstSymbolWithNameAndType(
g_gdb_object_getClass, eSymbolTypeCode) != nullptr);
- RegisterObjCExceptionRecognizer();
+ RegisterObjCExceptionRecognizer(process);
}
bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress(
@@ -840,7 +840,9 @@ AppleObjCRuntimeV2::CreateExceptionResolver(const BreakpointSP &bkpt,
return resolver_sp;
}
-UtilityFunction *AppleObjCRuntimeV2::CreateObjectChecker(const char *name) {
+llvm::Expected<std::unique_ptr<UtilityFunction>>
+AppleObjCRuntimeV2::CreateObjectChecker(std::string name,
+ ExecutionContext &exe_ctx) {
char check_function_code[2048];
int len = 0;
@@ -861,7 +863,8 @@ UtilityFunction *AppleObjCRuntimeV2::CreateObjectChecker(const char *name) {
if ($responds == (signed char) 0)
*((volatile int *)0) = 'ocgc';
}
- })", name);
+ })",
+ name.c_str());
} else {
len = ::snprintf(check_function_code, sizeof(check_function_code), R"(
extern "C" void *gdb_class_getClass(void *);
@@ -881,15 +884,15 @@ UtilityFunction *AppleObjCRuntimeV2::CreateObjectChecker(const char *name) {
if ($responds == (signed char) 0)
*((volatile int *)0) = 'ocgc';
}
- })", name);
+ })",
+ name.c_str());
}
assert(len < (int)sizeof(check_function_code));
UNUSED_IF_ASSERT_DISABLED(len);
- Status error;
- return GetTargetRef().GetUtilityFunctionForLanguage(
- check_function_code, eLanguageTypeObjC, name, error);
+ return GetTargetRef().CreateUtilityFunction(check_function_code, name,
+ eLanguageTypeC, exe_ctx);
}
size_t AppleObjCRuntimeV2::GetByteOffsetForIvar(CompilerType &parent_ast_type,
@@ -1175,28 +1178,6 @@ AppleObjCRuntimeV2::GetClassDescriptorFromISA(ObjCISA isa) {
return class_descriptor_sp;
}
-static std::pair<bool, ConstString> ObjCGetClassNameRaw(
- AppleObjCRuntime::ObjCISA isa,
- Process *process) {
- StreamString expr_string;
- std::string input = std::to_string(isa);
- expr_string.Printf("(const char *)objc_debug_class_getNameRaw(%s)",
- input.c_str());
-
- ValueObjectSP result_sp;
- EvaluateExpressionOptions eval_options;
- eval_options.SetLanguage(lldb::eLanguageTypeObjC);
- eval_options.SetResultIsInternal(true);
- eval_options.SetGenerateDebugInfo(true);
- eval_options.SetTimeout(process->GetUtilityExpressionTimeout());
- auto eval_result = process->GetTarget().EvaluateExpression(
- expr_string.GetData(),
- process->GetThreadList().GetSelectedThread()->GetSelectedFrame().get(),
- result_sp, eval_options);
- ConstString type_name(result_sp->GetSummaryAsCString());
- return std::make_pair(eval_result == eExpressionCompleted, type_name);
-}
-
ObjCLanguageRuntime::ClassDescriptorSP
AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) {
ClassDescriptorSP objc_class_sp;
@@ -1232,10 +1213,7 @@ AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) {
return objc_class_sp;
objc_class_sp = GetClassDescriptorFromISA(isa);
-
- if (objc_class_sp)
- return objc_class_sp;
- else {
+ if (isa && !objc_class_sp) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS |
LIBLLDB_LOG_TYPES));
LLDB_LOGF(log,
@@ -1244,13 +1222,6 @@ AppleObjCRuntimeV2::GetClassDescriptor(ValueObject &valobj) {
"not in class descriptor cache 0x%" PRIx64,
isa_pointer, isa);
}
-
- ClassDescriptorSP descriptor_sp(new ClassDescriptorV2(*this, isa, nullptr));
- auto resolved = ObjCGetClassNameRaw(isa, process);
- if (resolved.first == true) {
- AddClass(isa, descriptor_sp, resolved.second.AsCString());
- objc_class_sp = descriptor_sp;
- }
return objc_class_sp;
}
@@ -1333,15 +1304,14 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
return DescriptorMapUpdateResult::Fail();
thread_sp->CalculateExecutionContext(exe_ctx);
- TypeSystemClang *ast = TypeSystemClang::GetScratch(process->GetTarget());
+ TypeSystemClang *ast =
+ ScratchTypeSystemClang::GetForTarget(process->GetTarget());
if (!ast)
return DescriptorMapUpdateResult::Fail();
Address function_address;
- DiagnosticManager diagnostics;
-
const uint32_t addr_size = process->GetAddressByteSize();
Status err;
@@ -1363,28 +1333,16 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
FunctionCaller *get_class_info_function = nullptr;
if (!m_get_class_info_code) {
- Status error;
- m_get_class_info_code.reset(GetTargetRef().GetUtilityFunctionForLanguage(
- g_get_dynamic_class_info_body, eLanguageTypeObjC,
- g_get_dynamic_class_info_name, error));
- if (error.Fail()) {
- LLDB_LOGF(log,
- "Failed to get Utility Function for implementation lookup: %s",
- error.AsCString());
- m_get_class_info_code.reset();
- } else {
- diagnostics.Clear();
-
- if (!m_get_class_info_code->Install(diagnostics, exe_ctx)) {
- if (log) {
- LLDB_LOGF(log, "Failed to install implementation lookup");
- diagnostics.Dump(log);
- }
- m_get_class_info_code.reset();
- }
- }
- if (!m_get_class_info_code)
+ auto utility_fn_or_error = GetTargetRef().CreateUtilityFunction(
+ g_get_dynamic_class_info_body, g_get_dynamic_class_info_name,
+ eLanguageTypeC, exe_ctx);
+ if (!utility_fn_or_error) {
+ LLDB_LOG_ERROR(
+ log, utility_fn_or_error.takeError(),
+ "Failed to get utility function for implementation lookup: {0}");
return DescriptorMapUpdateResult::Fail();
+ }
+ m_get_class_info_code = std::move(*utility_fn_or_error);
// Next make the runner function for our implementation utility function.
Value value;
@@ -1398,6 +1356,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
arguments.PushValue(value);
arguments.PushValue(value);
+ Status error;
get_class_info_function = m_get_class_info_code->MakeFunctionCaller(
clang_uint32_t_type, arguments, thread_sp, error);
@@ -1410,17 +1369,13 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
} else {
get_class_info_function = m_get_class_info_code->GetFunctionCaller();
if (!get_class_info_function) {
- if (log) {
- LLDB_LOGF(log, "Failed to get implementation lookup function caller.");
- diagnostics.Dump(log);
- }
-
+ LLDB_LOGF(log, "Failed to get implementation lookup function caller.");
return DescriptorMapUpdateResult::Fail();
}
arguments = get_class_info_function->GetArgumentValues();
}
- diagnostics.Clear();
+ DiagnosticManager diagnostics;
const uint32_t class_info_byte_size = addr_size + 4;
const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
@@ -1593,15 +1548,14 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
return DescriptorMapUpdateResult::Fail();
thread_sp->CalculateExecutionContext(exe_ctx);
- TypeSystemClang *ast = TypeSystemClang::GetScratch(process->GetTarget());
+ TypeSystemClang *ast =
+ ScratchTypeSystemClang::GetForTarget(process->GetTarget());
if (!ast)
return DescriptorMapUpdateResult::Fail();
Address function_address;
- DiagnosticManager diagnostics;
-
const uint32_t addr_size = process->GetAddressByteSize();
Status err;
@@ -1636,10 +1590,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process);
if (objc_runtime) {
- const ModuleList &images = process->GetTarget().GetImages();
- std::lock_guard<std::recursive_mutex> guard(images.GetMutex());
- for (size_t i = 0; i < images.GetSize(); ++i) {
- lldb::ModuleSP mod_sp = images.GetModuleAtIndexUnlocked(i);
+ for (lldb::ModuleSP mod_sp : process->GetTarget().GetImages().Modules()) {
if (objc_runtime->IsModuleObjCLibrary(mod_sp)) {
const Symbol *symbol =
mod_sp->FindFirstSymbolWithNameAndType(g_class_getNameRaw_symbol_name,
@@ -1663,29 +1614,17 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
shared_class_expression += g_get_shared_cache_class_info_body;
- m_get_shared_cache_class_info_code.reset(
- GetTargetRef().GetUtilityFunctionForLanguage(
- shared_class_expression.c_str(), eLanguageTypeObjC,
- g_get_shared_cache_class_info_name, error));
- if (error.Fail()) {
- LLDB_LOGF(log,
- "Failed to get Utility function for implementation lookup: %s.",
- error.AsCString());
- m_get_shared_cache_class_info_code.reset();
- } else {
- diagnostics.Clear();
-
- if (!m_get_shared_cache_class_info_code->Install(diagnostics, exe_ctx)) {
- if (log) {
- LLDB_LOGF(log, "Failed to install implementation lookup.");
- diagnostics.Dump(log);
- }
- m_get_shared_cache_class_info_code.reset();
- }
+ auto utility_fn_or_error = exe_ctx.GetTargetRef().CreateUtilityFunction(
+ std::move(shared_class_expression), g_get_shared_cache_class_info_name,
+ eLanguageTypeC, exe_ctx);
+ if (!utility_fn_or_error) {
+ LLDB_LOG_ERROR(
+ log, utility_fn_or_error.takeError(),
+ "Failed to get utility function for implementation lookup: {0}");
+ return DescriptorMapUpdateResult::Fail();
}
- if (!m_get_shared_cache_class_info_code)
- return DescriptorMapUpdateResult::Fail();
+ m_get_shared_cache_class_info_code = std::move(*utility_fn_or_error);
// Next make the function caller for our implementation utility function.
Value value;
@@ -1714,7 +1653,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
arguments = get_shared_cache_class_info_function->GetArgumentValues();
}
- diagnostics.Clear();
+ DiagnosticManager diagnostics;
const uint32_t class_info_byte_size = addr_size + 4;
const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
@@ -1889,10 +1828,9 @@ lldb::addr_t AppleObjCRuntimeV2::GetSharedCacheReadOnlyAddress() {
}
void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
+ LLDB_SCOPED_TIMER();
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
// Else we need to check with our process to see when the map was updated.
Process *process = GetProcess();
@@ -2669,7 +2607,7 @@ class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame {
if (!abi) return;
TypeSystemClang *clang_ast_context =
- TypeSystemClang::GetScratch(process_sp->GetTarget());
+ ScratchTypeSystemClang::GetForTarget(process_sp->GetTarget());
if (!clang_ast_context)
return;
CompilerType voidstar =
@@ -2709,18 +2647,19 @@ class ObjCExceptionThrowFrameRecognizer : public StackFrameRecognizer {
return lldb::RecognizedStackFrameSP(
new ObjCExceptionRecognizedStackFrame(frame));
};
+ std::string GetName() override {
+ return "ObjC Exception Throw StackFrame Recognizer";
+ }
};
-static void RegisterObjCExceptionRecognizer() {
- static llvm::once_flag g_once_flag;
- llvm::call_once(g_once_flag, []() {
- FileSpec module;
- ConstString function;
- std::tie(module, function) = AppleObjCRuntime::GetExceptionThrowLocation();
- std::vector<ConstString> symbols = {function};
- StackFrameRecognizerManager::AddRecognizer(
- StackFrameRecognizerSP(new ObjCExceptionThrowFrameRecognizer()),
- module.GetFilename(), symbols,
- /*first_instruction_only*/ true);
- });
+static void RegisterObjCExceptionRecognizer(Process *process) {
+ FileSpec module;
+ ConstString function;
+ std::tie(module, function) = AppleObjCRuntime::GetExceptionThrowLocation();
+ std::vector<ConstString> symbols = {function};
+
+ process->GetTarget().GetFrameRecognizerManager().AddRecognizer(
+ StackFrameRecognizerSP(new ObjCExceptionThrowFrameRecognizer()),
+ module.GetFilename(), symbols,
+ /*first_instruction_only*/ true);
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index 99264d556da5..c6fb6ea26b98 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -53,7 +53,8 @@ public:
Address &address,
Value::ValueType &value_type) override;
- UtilityFunction *CreateObjectChecker(const char *) override;
+ llvm::Expected<std::unique_ptr<UtilityFunction>>
+ CreateObjectChecker(std::string name, ExecutionContext &exe_ctx) override;
// PluginInterface protocol
ConstString GetPluginName() override;
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index c96768c9f585..bcc1f6fd339f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -452,15 +452,11 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::InitializeVTableSymbols() {
if (process_sp) {
Target &target = process_sp->GetTarget();
- const ModuleList &target_modules = target.GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
- size_t num_modules = target_modules.GetSize();
if (!m_objc_module_sp) {
- for (size_t i = 0; i < num_modules; i++) {
+ for (ModuleSP module_sp : target.GetImages().Modules()) {
if (ObjCLanguageRuntime::Get(*process_sp)
- ->IsModuleObjCLibrary(
- target_modules.GetModuleAtIndexUnlocked(i))) {
- m_objc_module_sp = target_modules.GetModuleAtIndexUnlocked(i);
+ ->IsModuleObjCLibrary(module_sp)) {
+ m_objc_module_sp = module_sp;
break;
}
}
@@ -521,7 +517,7 @@ bool AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines(
const ABI *abi = process->GetABI().get();
TypeSystemClang *clang_ast_context =
- TypeSystemClang::GetScratch(process->GetTarget());
+ ScratchTypeSystemClang::GetForTarget(process->GetTarget());
if (!clang_ast_context)
return false;
@@ -798,7 +794,6 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread,
ValueList &dispatch_values) {
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;
@@ -812,35 +807,24 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread,
if (!m_impl_code) {
if (m_lookup_implementation_function_code != nullptr) {
- Status error;
- m_impl_code.reset(exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(
- m_lookup_implementation_function_code, eLanguageTypeObjC,
- g_lookup_implementation_function_name, error));
- if (error.Fail()) {
- LLDB_LOGF(
- log,
- "Failed to get Utility Function for implementation lookup: %s.",
- error.AsCString());
- m_impl_code.reset();
- return args_addr;
- }
-
- if (!m_impl_code->Install(diagnostics, exe_ctx)) {
- if (log) {
- LLDB_LOGF(log, "Failed to install implementation lookup.");
- diagnostics.Dump(log);
- }
- m_impl_code.reset();
+ auto utility_fn_or_error = exe_ctx.GetTargetRef().CreateUtilityFunction(
+ m_lookup_implementation_function_code,
+ g_lookup_implementation_function_name, eLanguageTypeC, exe_ctx);
+ if (!utility_fn_or_error) {
+ LLDB_LOG_ERROR(
+ log, utility_fn_or_error.takeError(),
+ "Failed to get Utility Function for implementation lookup: {0}.");
return args_addr;
}
+ m_impl_code = std::move(*utility_fn_or_error);
} else {
LLDB_LOGF(log, "No method lookup implementation code.");
return LLDB_INVALID_ADDRESS;
}
// Next make the runner function for our implementation utility function.
- TypeSystemClang *clang_ast_context =
- TypeSystemClang::GetScratch(thread.GetProcess()->GetTarget());
+ TypeSystemClang *clang_ast_context = ScratchTypeSystemClang::GetForTarget(
+ thread.GetProcess()->GetTarget());
if (!clang_ast_context)
return LLDB_INVALID_ADDRESS;
@@ -861,14 +845,13 @@ AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread,
}
}
- 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...
+ DiagnosticManager diagnostics;
if (!impl_function_caller->WriteFunctionArguments(
exe_ctx, args_addr, dispatch_values, diagnostics)) {
if (log) {
@@ -944,7 +927,8 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan(Thread &thread,
TargetSP target_sp(thread.CalculateTarget());
- TypeSystemClang *clang_ast_context = TypeSystemClang::GetScratch(*target_sp);
+ TypeSystemClang *clang_ast_context =
+ ScratchTypeSystemClang::GetForTarget(*target_sp);
if (!clang_ast_context)
return ret_plan_sp;
diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
index c43acf54bbcd..683eff777728 100644
--- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
+++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
@@ -251,7 +251,8 @@ public:
llvm::Optional<CompilerType> GetRuntimeType(CompilerType base_type) override;
- virtual UtilityFunction *CreateObjectChecker(const char *) = 0;
+ virtual llvm::Expected<std::unique_ptr<UtilityFunction>>
+ CreateObjectChecker(std::string name, ExecutionContext &exe_ctx) = 0;
virtual ObjCRuntimeVersions GetRuntimeVersion() const {
return ObjCRuntimeVersions::eObjC_VersionUnknown;
diff --git a/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp b/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp
index 333113a0b17a..7d9976285192 100644
--- a/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp
@@ -36,13 +36,8 @@ MemoryHistorySP MemoryHistoryASan::CreateInstance(const ProcessSP &process_sp) {
Target &target = process_sp->GetTarget();
- const ModuleList &target_modules = target.GetImages();
- 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) {
- Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
-
- const Symbol *symbol = module_pointer->FindFirstSymbolWithNameAndType(
+ for (ModuleSP module_sp : target.GetImages().Modules()) {
+ const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(
ConstString("__asan_get_alloc_stack"), lldb::eSymbolTypeAny);
if (symbol != nullptr)
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
index 83cf9f8bd269..211eb9ce0d3a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
@@ -300,9 +300,7 @@ ObjectContainer *ObjectContainerBSDArchive::CreateInstance(
DataExtractor data;
data.SetData(data_sp, data_offset, length);
if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data)) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat,
+ LLDB_SCOPED_TIMERF(
"ObjectContainerBSDArchive::CreateInstance (module = %s, file = "
"%p, file_offset = 0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
module_sp->GetFileSpec().GetPath().c_str(),
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index bca575b7f884..cad9ce218b10 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -296,9 +296,23 @@ static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) {
return arch_variant;
}
+static uint32_t riscvVariantFromElfFlags(const elf::ELFHeader &header) {
+ uint32_t fileclass = header.e_ident[EI_CLASS];
+ switch (fileclass) {
+ case llvm::ELF::ELFCLASS32:
+ return ArchSpec::eRISCVSubType_riscv32;
+ case llvm::ELF::ELFCLASS64:
+ return ArchSpec::eRISCVSubType_riscv64;
+ default:
+ return ArchSpec::eRISCVSubType_unknown;
+ }
+}
+
static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) {
if (header.e_machine == llvm::ELF::EM_MIPS)
return mipsVariantFromElfFlags(header);
+ else if (header.e_machine == llvm::ELF::EM_RISCV)
+ return riscvVariantFromElfFlags(header);
return LLDB_INVALID_CPUTYPE;
}
@@ -576,9 +590,7 @@ size_t ObjectFileELF::GetModuleSpecifications(
uint32_t core_notes_crc = 0;
if (!gnu_debuglink_crc) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- lldb_private::Timer scoped_timer(
- func_cat,
+ LLDB_SCOPED_TIMERF(
"Calculating module crc32 %s with size %" PRIu64 " KiB",
file.GetLastPathComponent().AsCString(),
(length - file_offset) / 1024);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp
new file mode 100644
index 000000000000..35a823e9a28f
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp
@@ -0,0 +1,197 @@
+//===-- ObjectFilePDB.cpp -------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ObjectFilePDB.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Utility/StreamString.h"
+#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/PDB.h"
+#include "llvm/Support/BinaryByteStream.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm::pdb;
+using namespace llvm::codeview;
+
+LLDB_PLUGIN_DEFINE(ObjectFilePDB)
+
+static UUID GetPDBUUID(InfoStream &IS) {
+ UUID::CvRecordPdb70 debug_info;
+ memcpy(&debug_info.Uuid, IS.getGuid().Guid, sizeof(debug_info.Uuid));
+ debug_info.Age = IS.getAge();
+ return UUID::fromCvRecord(debug_info);
+}
+
+char ObjectFilePDB::ID;
+
+void ObjectFilePDB::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ CreateMemoryInstance, GetModuleSpecifications);
+}
+
+void ObjectFilePDB::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+ConstString ObjectFilePDB::GetPluginNameStatic() {
+ static ConstString g_name("pdb");
+ return g_name;
+}
+
+ArchSpec ObjectFilePDB::GetArchitecture() {
+ auto dbi_stream = m_file_up->getPDBDbiStream();
+ if (!dbi_stream) {
+ llvm::consumeError(dbi_stream.takeError());
+ return ArchSpec();
+ }
+
+ PDB_Machine machine = dbi_stream->getMachineType();
+ switch (machine) {
+ default:
+ break;
+ case PDB_Machine::Amd64:
+ case PDB_Machine::x86:
+ case PDB_Machine::PowerPC:
+ case PDB_Machine::PowerPCFP:
+ case PDB_Machine::Arm:
+ case PDB_Machine::ArmNT:
+ case PDB_Machine::Thumb:
+ case PDB_Machine::Arm64:
+ ArchSpec arch;
+ arch.SetArchitecture(eArchTypeCOFF, static_cast<int>(machine),
+ LLDB_INVALID_CPUTYPE);
+ return arch;
+ }
+ return ArchSpec();
+}
+
+bool ObjectFilePDB::initPDBFile() {
+ m_file_up = loadPDBFile(m_file.GetPath(), m_allocator);
+ if (!m_file_up)
+ return false;
+ auto info_stream = m_file_up->getPDBInfoStream();
+ if (!info_stream) {
+ llvm::consumeError(info_stream.takeError());
+ return false;
+ }
+ m_uuid = GetPDBUUID(*info_stream);
+ return true;
+}
+
+ObjectFile *
+ObjectFilePDB::CreateInstance(const ModuleSP &module_sp, DataBufferSP &data_sp,
+ offset_t data_offset, const FileSpec *file,
+ offset_t file_offset, offset_t length) {
+ auto objfile_up = std::make_unique<ObjectFilePDB>(
+ module_sp, data_sp, data_offset, file, file_offset, length);
+ if (!objfile_up->initPDBFile())
+ return nullptr;
+ return objfile_up.release();
+}
+
+ObjectFile *ObjectFilePDB::CreateMemoryInstance(const ModuleSP &module_sp,
+ DataBufferSP &data_sp,
+ const ProcessSP &process_sp,
+ addr_t header_addr) {
+ return nullptr;
+}
+
+size_t ObjectFilePDB::GetModuleSpecifications(
+ const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset,
+ offset_t file_offset, offset_t length, ModuleSpecList &specs) {
+ const size_t initial_count = specs.GetSize();
+ ModuleSpec module_spec(file);
+ llvm::BumpPtrAllocator allocator;
+ std::unique_ptr<PDBFile> pdb_file = loadPDBFile(file.GetPath(), allocator);
+ if (!pdb_file)
+ return initial_count;
+
+ auto info_stream = pdb_file->getPDBInfoStream();
+ if (!info_stream) {
+ llvm::consumeError(info_stream.takeError());
+ return initial_count;
+ }
+ auto dbi_stream = pdb_file->getPDBDbiStream();
+ if (!dbi_stream) {
+ llvm::consumeError(dbi_stream.takeError());
+ return initial_count;
+ }
+
+ lldb_private::UUID &uuid = module_spec.GetUUID();
+ uuid = GetPDBUUID(*info_stream);
+
+ ArchSpec &module_arch = module_spec.GetArchitecture();
+ switch (dbi_stream->getMachineType()) {
+ case PDB_Machine::Amd64:
+ module_arch.SetTriple("x86_64-pc-windows");
+ specs.Append(module_spec);
+ break;
+ case PDB_Machine::x86:
+ module_arch.SetTriple("i386-pc-windows");
+ specs.Append(module_spec);
+ module_arch.SetTriple("i686-pc-windows");
+ specs.Append(module_spec);
+ break;
+ case PDB_Machine::ArmNT:
+ module_arch.SetTriple("armv7-pc-windows");
+ specs.Append(module_spec);
+ break;
+ case PDB_Machine::Arm64:
+ module_arch.SetTriple("aarch64-pc-windows");
+ specs.Append(module_spec);
+ break;
+ default:
+ break;
+ }
+
+ return specs.GetSize() - initial_count;
+}
+
+ObjectFilePDB::ObjectFilePDB(const ModuleSP &module_sp, DataBufferSP &data_sp,
+ offset_t data_offset, const FileSpec *file,
+ offset_t offset, offset_t length)
+ : ObjectFile(module_sp, file, offset, length, data_sp, data_offset) {}
+
+std::unique_ptr<PDBFile>
+ObjectFilePDB::loadPDBFile(std::string PdbPath,
+ llvm::BumpPtrAllocator &Allocator) {
+ llvm::file_magic magic;
+ auto ec = llvm::identify_magic(PdbPath, magic);
+ if (ec || magic != llvm::file_magic::pdb)
+ return nullptr;
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ErrorOrBuffer =
+ llvm::MemoryBuffer::getFile(PdbPath, /*FileSize=*/-1,
+ /*RequiresNullTerminator=*/false);
+ if (!ErrorOrBuffer)
+ return nullptr;
+ std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
+
+ llvm::StringRef Path = Buffer->getBufferIdentifier();
+ auto Stream = std::make_unique<llvm::MemoryBufferByteStream>(
+ std::move(Buffer), llvm::support::little);
+
+ auto File = std::make_unique<PDBFile>(Path, std::move(Stream), Allocator);
+ if (auto EC = File->parseFileHeaders()) {
+ llvm::consumeError(std::move(EC));
+ return nullptr;
+ }
+ if (auto EC = File->parseStreamData()) {
+ llvm::consumeError(std::move(EC));
+ return nullptr;
+ }
+
+ return File;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
new file mode 100644
index 000000000000..19dd46b31406
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
@@ -0,0 +1,107 @@
+//===-- ObjectFilePDB.h --------------------------------------- -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_PDB_OBJECTFILEPDB_H
+#define LLDB_SOURCE_PLUGINS_OBJECTFILE_PDB_OBJECTFILEPDB_H
+
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+
+namespace lldb_private {
+
+class ObjectFilePDB : public ObjectFile {
+public:
+ // Static Functions
+ static void Initialize();
+ static void Terminate();
+
+ static ConstString GetPluginNameStatic();
+ static const char *GetPluginDescriptionStatic() {
+ return "PDB object file reader.";
+ }
+
+ static std::unique_ptr<llvm::pdb::PDBFile>
+ loadPDBFile(std::string PdbPath, llvm::BumpPtrAllocator &Allocator);
+
+ static ObjectFile *
+ CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, const FileSpec *file,
+ lldb::offset_t file_offset, lldb::offset_t length);
+
+ static ObjectFile *CreateMemoryInstance(const lldb::ModuleSP &module_sp,
+ lldb::DataBufferSP &data_sp,
+ const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr);
+
+ static size_t GetModuleSpecifications(const FileSpec &file,
+ lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ ModuleSpecList &specs);
+
+ // PluginInterface protocol
+ ConstString GetPluginName() override { return GetPluginNameStatic(); }
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ // LLVM RTTI support
+ static char ID;
+ bool isA(const void *ClassID) const override {
+ return ClassID == &ID || ObjectFile::isA(ClassID);
+ }
+ static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }
+
+ // ObjectFile Protocol.
+ uint32_t GetAddressByteSize() const override { return 8; }
+
+ lldb::ByteOrder GetByteOrder() const override {
+ return lldb::eByteOrderLittle;
+ }
+
+ bool ParseHeader() override { return true; }
+
+ bool IsExecutable() const override { return false; }
+
+ Symtab *GetSymtab() override { return nullptr; }
+
+ bool IsStripped() override { return false; }
+
+ // No section in PDB file.
+ void CreateSections(SectionList &unified_section_list) override {}
+
+ void Dump(Stream *s) override {}
+
+ ArchSpec GetArchitecture() override;
+
+ UUID GetUUID() override { return m_uuid; }
+
+ uint32_t GetDependentModules(FileSpecList &files) override { return 0; }
+
+ Type CalculateType() override { return eTypeDebugInfo; }
+
+ Strata CalculateStrata() override { return eStrataUser; }
+
+ llvm::pdb::PDBFile &GetPDBFile() { return *m_file_up; }
+
+ ObjectFilePDB(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, const FileSpec *file,
+ lldb::offset_t offset, lldb::offset_t length);
+
+private:
+ UUID m_uuid;
+ llvm::BumpPtrAllocator m_allocator;
+ std::unique_ptr<llvm::pdb::PDBFile> m_file_up;
+
+ bool initPDBFile();
+};
+
+} // namespace lldb_private
+#endif // LLDB_PLUGINS_OBJECTFILE_PDB_OBJECTFILEPDB_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
index 91150fa02ebc..6c29c2326212 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
@@ -253,6 +253,43 @@ bool ObjectFileWasm::ParseHeader() {
Symtab *ObjectFileWasm::GetSymtab() { return nullptr; }
+static SectionType GetSectionTypeFromName(llvm::StringRef Name) {
+ if (Name.consume_front(".debug_") || Name.consume_front(".zdebug_")) {
+ return llvm::StringSwitch<SectionType>(Name)
+ .Case("abbrev", eSectionTypeDWARFDebugAbbrev)
+ .Case("abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo)
+ .Case("addr", eSectionTypeDWARFDebugAddr)
+ .Case("aranges", eSectionTypeDWARFDebugAranges)
+ .Case("cu_index", eSectionTypeDWARFDebugCuIndex)
+ .Case("frame", eSectionTypeDWARFDebugFrame)
+ .Case("info", eSectionTypeDWARFDebugInfo)
+ .Case("info.dwo", eSectionTypeDWARFDebugInfoDwo)
+ .Cases("line", "line.dwo", eSectionTypeDWARFDebugLine)
+ .Cases("line_str", "line_str.dwo", eSectionTypeDWARFDebugLineStr)
+ .Case("loc", eSectionTypeDWARFDebugLoc)
+ .Case("loc.dwo", eSectionTypeDWARFDebugLocDwo)
+ .Case("loclists", eSectionTypeDWARFDebugLocLists)
+ .Case("loclists.dwo", eSectionTypeDWARFDebugLocListsDwo)
+ .Case("macinfo", eSectionTypeDWARFDebugMacInfo)
+ .Cases("macro", "macro.dwo", eSectionTypeDWARFDebugMacro)
+ .Case("names", eSectionTypeDWARFDebugNames)
+ .Case("pubnames", eSectionTypeDWARFDebugPubNames)
+ .Case("pubtypes", eSectionTypeDWARFDebugPubTypes)
+ .Case("ranges", eSectionTypeDWARFDebugRanges)
+ .Case("rnglists", eSectionTypeDWARFDebugRngLists)
+ .Case("rnglists.dwo", eSectionTypeDWARFDebugRngListsDwo)
+ .Case("str", eSectionTypeDWARFDebugStr)
+ .Case("str.dwo", eSectionTypeDWARFDebugStrDwo)
+ .Case("str_offsets", eSectionTypeDWARFDebugStrOffsets)
+ .Case("str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo)
+ .Case("tu_index", eSectionTypeDWARFDebugTuIndex)
+ .Case("types", eSectionTypeDWARFDebugTypes)
+ .Case("types.dwo", eSectionTypeDWARFDebugTypesDwo)
+ .Default(eSectionTypeOther);
+ }
+ return eSectionTypeOther;
+}
+
void ObjectFileWasm::CreateSections(SectionList &unified_section_list) {
if (m_sections_up)
return;
@@ -280,29 +317,7 @@ void ObjectFileWasm::CreateSections(SectionList &unified_section_list) {
// Code section.
vm_addr = 0;
} else {
- section_type =
- llvm::StringSwitch<SectionType>(sect_info.name.GetStringRef())
- .Case(".debug_abbrev", eSectionTypeDWARFDebugAbbrev)
- .Case(".debug_addr", eSectionTypeDWARFDebugAddr)
- .Case(".debug_aranges", eSectionTypeDWARFDebugAranges)
- .Case(".debug_cu_index", eSectionTypeDWARFDebugCuIndex)
- .Case(".debug_frame", eSectionTypeDWARFDebugFrame)
- .Case(".debug_info", eSectionTypeDWARFDebugInfo)
- .Case(".debug_line", eSectionTypeDWARFDebugLine)
- .Case(".debug_line_str", eSectionTypeDWARFDebugLineStr)
- .Case(".debug_loc", eSectionTypeDWARFDebugLoc)
- .Case(".debug_loclists", eSectionTypeDWARFDebugLocLists)
- .Case(".debug_macinfo", eSectionTypeDWARFDebugMacInfo)
- .Case(".debug_macro", eSectionTypeDWARFDebugMacro)
- .Case(".debug_names", eSectionTypeDWARFDebugNames)
- .Case(".debug_pubnames", eSectionTypeDWARFDebugPubNames)
- .Case(".debug_pubtypes", eSectionTypeDWARFDebugPubTypes)
- .Case(".debug_ranges", eSectionTypeDWARFDebugRanges)
- .Case(".debug_rnglists", eSectionTypeDWARFDebugRngLists)
- .Case(".debug_str", eSectionTypeDWARFDebugStr)
- .Case(".debug_str_offsets", eSectionTypeDWARFDebugStrOffsets)
- .Case(".debug_types", eSectionTypeDWARFDebugTypes)
- .Default(eSectionTypeOther);
+ section_type = GetSectionTypeFromName(sect_info.name.GetStringRef());
if (section_type == eSectionTypeOther)
continue;
section_name = sect_info.name;
diff --git a/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
index 417aa2e21436..4350010f0296 100644
--- a/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -133,8 +133,8 @@ DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() {
if (!dictionary)
return nullptr;
- m_register_info_up.reset(new DynamicRegisterInfo(
- *dictionary, m_process->GetTarget().GetArchitecture()));
+ m_register_info_up = std::make_unique<DynamicRegisterInfo>(
+ *dictionary, m_process->GetTarget().GetArchitecture());
assert(m_register_info_up->GetNumRegisters() > 0);
assert(m_register_info_up->GetNumRegisterSets() > 0);
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
index 97c2f22b505f..6b39a83fd668 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -27,6 +27,9 @@
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Host.h"
+
// Define these constants from FreeBSD mman.h for use when targeting remote
// FreeBSD systems even when host has different values.
#define MAP_PRIVATE 0x0002
@@ -125,8 +128,6 @@ PlatformFreeBSD::PlatformFreeBSD(bool is_host)
: PlatformPOSIX(is_host) // This is the local host platform
{}
-PlatformFreeBSD::~PlatformFreeBSD() = default;
-
bool PlatformFreeBSD::GetSupportedArchitectureAtIndex(uint32_t idx,
ArchSpec &arch) {
if (IsHost()) {
@@ -213,92 +214,13 @@ void PlatformFreeBSD::GetStatus(Stream &strm) {
#endif
}
-size_t
-PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode(Target &target,
- BreakpointSite *bp_site) {
- switch (target.GetArchitecture().GetMachine()) {
- case llvm::Triple::arm: {
- lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
- AddressClass addr_class = AddressClass::eUnknown;
-
- if (bp_loc_sp) {
- addr_class = bp_loc_sp->GetAddress().GetAddressClass();
- if (addr_class == AddressClass::eUnknown &&
- (bp_loc_sp->GetAddress().GetFileAddress() & 1))
- addr_class = AddressClass::eCodeAlternateISA;
- }
-
- if (addr_class == AddressClass::eCodeAlternateISA) {
- // TODO: Enable when FreeBSD supports thumb breakpoints.
- // FreeBSD kernel as of 10.x, does not support thumb breakpoints
- return 0;
- }
-
- static const uint8_t g_arm_breakpoint_opcode[] = {0xFE, 0xDE, 0xFF, 0xE7};
- size_t trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
- assert(bp_site);
- if (bp_site->SetTrapOpcode(g_arm_breakpoint_opcode, trap_opcode_size))
- return trap_opcode_size;
- }
- LLVM_FALLTHROUGH;
- default:
- return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site);
- }
-}
-
-Status PlatformFreeBSD::LaunchProcess(ProcessLaunchInfo &launch_info) {
- Status error;
- if (IsHost()) {
- error = Platform::LaunchProcess(launch_info);
- } else {
- if (m_remote_platform_sp)
- error = m_remote_platform_sp->LaunchProcess(launch_info);
- else
- error.SetErrorString("the platform is not currently connected");
- }
- return error;
-}
-
-lldb::ProcessSP PlatformFreeBSD::Attach(ProcessAttachInfo &attach_info,
- Debugger &debugger, Target *target,
- Status &error) {
- lldb::ProcessSP process_sp;
+bool PlatformFreeBSD::CanDebugProcess() {
if (IsHost()) {
- if (target == nullptr) {
- TargetSP new_target_sp;
- ArchSpec emptyArchSpec;
-
- error = debugger.GetTargetList().CreateTarget(
- debugger, "", emptyArchSpec, eLoadDependentsNo, m_remote_platform_sp,
- new_target_sp);
- target = new_target_sp.get();
- } else
- error.Clear();
-
- if (target && error.Success()) {
- debugger.GetTargetList().SetSelectedTarget(target);
- // The freebsd always currently uses the GDB remote debugger plug-in so
- // even when debugging locally we are debugging remotely! Just like the
- // darwin plugin.
- process_sp = target->CreateProcess(
- attach_info.GetListenerForProcess(debugger), "gdb-remote", nullptr);
-
- if (process_sp)
- error = process_sp->Attach(attach_info);
- }
+ return true;
} else {
- if (m_remote_platform_sp)
- process_sp =
- m_remote_platform_sp->Attach(attach_info, debugger, target, error);
- else
- error.SetErrorString("the platform is not currently connected");
+ // If we're connected, we can debug.
+ return IsConnected();
}
- return process_sp;
-}
-
-// FreeBSD processes cannot yet be launched by spawning and attaching.
-bool PlatformFreeBSD::CanDebugProcess() {
- return false;
}
void PlatformFreeBSD::CalculateTrapHandlerSymbolNames() {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
index 56f2f2771d12..4fd10fb1be73 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
@@ -18,8 +18,6 @@ class PlatformFreeBSD : public PlatformPOSIX {
public:
PlatformFreeBSD(bool is_host);
- ~PlatformFreeBSD() override;
-
static void Initialize();
static void Terminate();
@@ -46,24 +44,12 @@ public:
bool CanDebugProcess() override;
- size_t GetSoftwareBreakpointTrapOpcode(Target &target,
- BreakpointSite *bp_site) override;
-
- Status LaunchProcess(ProcessLaunchInfo &launch_info) override;
-
- lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger,
- Target *target, Status &error) override;
-
void CalculateTrapHandlerSymbolNames() override;
MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr,
lldb::addr_t length, unsigned prot,
unsigned flags, lldb::addr_t fd,
lldb::addr_t offset) override;
-
-private:
- PlatformFreeBSD(const PlatformFreeBSD &) = delete;
- const PlatformFreeBSD &operator=(const PlatformFreeBSD &) = delete;
};
} // namespace platform_freebsd
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
index caebd79c853e..a5d73c942830 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
@@ -117,8 +117,6 @@ PlatformNetBSD::PlatformNetBSD(bool is_host)
: PlatformPOSIX(is_host) // This is the local host platform
{}
-PlatformNetBSD::~PlatformNetBSD() = default;
-
bool PlatformNetBSD::GetSupportedArchitectureAtIndex(uint32_t idx,
ArchSpec &arch) {
if (IsHost()) {
@@ -187,9 +185,9 @@ void PlatformNetBSD::GetStatus(Stream &strm) {
#endif
}
-int32_t
+uint32_t
PlatformNetBSD::GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) {
- int32_t resume_count = 0;
+ uint32_t resume_count = 0;
// Always resume past the initial stop when we use eLaunchFlagDebug
if (launch_info.GetFlags().Test(eLaunchFlagDebug)) {
@@ -231,121 +229,6 @@ bool PlatformNetBSD::CanDebugProcess() {
}
}
-// For local debugging, NetBSD will override the debug logic to use llgs-launch
-// rather than lldb-launch, llgs-attach. This differs from current lldb-
-// launch, debugserver-attach approach on MacOSX.
-lldb::ProcessSP
-PlatformNetBSD::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
- Target *target, // Can be NULL, if NULL create a new
- // target, else use existing one
- Status &error) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- LLDB_LOG(log, "target {0}", target);
-
- // If we're a remote host, use standard behavior from parent class.
- if (!IsHost())
- return PlatformPOSIX::DebugProcess(launch_info, debugger, target, error);
-
- //
- // For local debugging, we'll insist on having ProcessGDBRemote create the
- // process.
- //
-
- ProcessSP process_sp;
-
- // Make sure we stop at the entry point
- launch_info.GetFlags().Set(eLaunchFlagDebug);
-
- // We always launch the process we are going to debug in a separate process
- // group, since then we can handle ^C interrupts ourselves w/o having to
- // worry about the target getting them as well.
- launch_info.SetLaunchInSeparateProcessGroup(true);
-
- // Ensure we have a target.
- if (target == nullptr) {
- LLDB_LOG(log, "creating new target");
- TargetSP new_target_sp;
- error = debugger.GetTargetList().CreateTarget(
- debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp);
- if (error.Fail()) {
- LLDB_LOG(log, "failed to create new target: {0}", error);
- return process_sp;
- }
-
- target = new_target_sp.get();
- if (!target) {
- error.SetErrorString("CreateTarget() returned nullptr");
- LLDB_LOG(log, "error: {0}", error);
- return process_sp;
- }
- }
-
- // Mark target as currently selected target.
- debugger.GetTargetList().SetSelectedTarget(target);
-
- // Now create the gdb-remote process.
- LLDB_LOG(log, "having target create process with gdb-remote plugin");
- process_sp =
- target->CreateProcess(launch_info.GetListener(), "gdb-remote", nullptr);
-
- if (!process_sp) {
- error.SetErrorString("CreateProcess() failed for gdb-remote process");
- LLDB_LOG(log, "error: {0}", error);
- return process_sp;
- }
-
- LLDB_LOG(log, "successfully created process");
- // Adjust launch for a hijacker.
- ListenerSP listener_sp;
- if (!launch_info.GetHijackListener()) {
- LLDB_LOG(log, "setting up hijacker");
- listener_sp =
- Listener::MakeListener("lldb.PlatformNetBSD.DebugProcess.hijack");
- launch_info.SetHijackListener(listener_sp);
- process_sp->HijackProcessEvents(listener_sp);
- }
-
- // Log file actions.
- if (log) {
- LLDB_LOG(log, "launching process with the following file actions:");
- StreamString stream;
- size_t i = 0;
- const FileAction *file_action;
- while ((file_action = launch_info.GetFileActionAtIndex(i++)) != nullptr) {
- file_action->Dump(stream);
- LLDB_LOG(log, "{0}", stream.GetData());
- stream.Clear();
- }
- }
-
- // Do the launch.
- error = process_sp->Launch(launch_info);
- if (error.Success()) {
- // Handle the hijacking of process events.
- if (listener_sp) {
- const StateType state = process_sp->WaitForProcessToStop(
- llvm::None, nullptr, false, listener_sp);
-
- LLDB_LOG(log, "pid {0} state {0}", process_sp->GetID(), state);
- }
-
- // Hook up process PTY if we have one (which we should for local debugging
- // with llgs).
- int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor();
- if (pty_fd != PseudoTerminal::invalid_fd) {
- process_sp->SetSTDIOFileDescriptor(pty_fd);
- LLDB_LOG(log, "hooked up STDIO pty to process");
- } else
- LLDB_LOG(log, "not using process STDIO pty");
- } else {
- LLDB_LOG(log, "{0}", error);
- // FIXME figure out appropriate cleanup here. Do we delete the target? Do
- // we delete the process? Does our caller do that?
- }
-
- return process_sp;
-}
-
void PlatformNetBSD::CalculateTrapHandlerSymbolNames() {
m_trap_handlers.push_back(ConstString("_sigtramp"));
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
index d53e58418884..e664f5181123 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
@@ -18,8 +18,6 @@ class PlatformNetBSD : public PlatformPOSIX {
public:
PlatformNetBSD(bool is_host);
- ~PlatformNetBSD() override;
-
static void Initialize();
static void Terminate();
@@ -44,24 +42,16 @@ public:
bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override;
- int32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) override;
+ uint32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) override;
bool CanDebugProcess() override;
- lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info,
- Debugger &debugger, Target *target,
- Status &error) override;
-
void CalculateTrapHandlerSymbolNames() override;
MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr,
lldb::addr_t length, unsigned prot,
unsigned flags, lldb::addr_t fd,
lldb::addr_t offset) override;
-
-private:
- PlatformNetBSD(const PlatformNetBSD &) = delete;
- const PlatformNetBSD &operator=(const PlatformNetBSD &) = delete;
};
} // namespace platform_netbsd
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
index a743970990a6..2cd024f56ec9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
@@ -123,8 +123,6 @@ PlatformOpenBSD::PlatformOpenBSD(bool is_host)
: PlatformPOSIX(is_host) // This is the local host platform
{}
-PlatformOpenBSD::~PlatformOpenBSD() = default;
-
bool PlatformOpenBSD::GetSupportedArchitectureAtIndex(uint32_t idx,
ArchSpec &arch) {
if (IsHost()) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h b/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h
index 9cfe32c3720c..e1402ae0ae9f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h
@@ -18,8 +18,6 @@ class PlatformOpenBSD : public PlatformPOSIX {
public:
PlatformOpenBSD(bool is_host);
- ~PlatformOpenBSD() override;
-
static void Initialize();
static void Terminate();
@@ -52,10 +50,6 @@ public:
lldb::addr_t length, unsigned prot,
unsigned flags, lldb::addr_t fd,
lldb::addr_t offset) override;
-
-private:
- PlatformOpenBSD(const PlatformOpenBSD &) = delete;
- const PlatformOpenBSD &operator=(const PlatformOpenBSD &) = delete;
};
} // namespace platform_openbsd
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index 180ea1d2cfd1..3628b0a2ce5e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -377,7 +377,6 @@ lldb::ProcessSP PlatformPOSIX::Attach(ProcessAttachInfo &attach_info,
}
if (target && error.Success()) {
- debugger.GetTargetList().SetSelectedTarget(target);
if (log) {
ModuleSP exe_module_sp = target->GetExecutableModule();
LLDB_LOGF(log, "PlatformPOSIX::%s set selected target to %p %s",
@@ -388,7 +387,7 @@ lldb::ProcessSP PlatformPOSIX::Attach(ProcessAttachInfo &attach_info,
process_sp =
target->CreateProcess(attach_info.GetListenerForProcess(debugger),
- attach_info.GetProcessPluginName(), nullptr);
+ "gdb-remote", nullptr, true);
if (process_sp) {
ListenerSP listener_sp = attach_info.GetHijackListener();
@@ -416,24 +415,113 @@ PlatformPOSIX::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
Target *target, // Can be NULL, if NULL create a new
// target, else use existing one
Status &error) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ LLDB_LOG(log, "target {0}", target);
+
ProcessSP process_sp;
- if (IsHost()) {
- // We are going to hand this process off to debugserver which will be in
- // charge of setting the exit status. However, we still need to reap it
- // from lldb. So, make sure we use a exit callback which does not set exit
- // status.
- const bool monitor_signals = false;
- launch_info.SetMonitorProcessCallback(
- &ProcessLaunchInfo::NoOpMonitorCallback, monitor_signals);
- process_sp = Platform::DebugProcess(launch_info, debugger, target, error);
- } else {
+ if (!IsHost()) {
if (m_remote_platform_sp)
process_sp = m_remote_platform_sp->DebugProcess(launch_info, debugger,
target, error);
else
error.SetErrorString("the platform is not currently connected");
+ return process_sp;
+ }
+
+ //
+ // For local debugging, we'll insist on having ProcessGDBRemote create the
+ // process.
+ //
+
+ // Make sure we stop at the entry point
+ launch_info.GetFlags().Set(eLaunchFlagDebug);
+
+ // We always launch the process we are going to debug in a separate process
+ // group, since then we can handle ^C interrupts ourselves w/o having to
+ // worry about the target getting them as well.
+ launch_info.SetLaunchInSeparateProcessGroup(true);
+
+ // Ensure we have a target.
+ if (target == nullptr) {
+ LLDB_LOG(log, "creating new target");
+ TargetSP new_target_sp;
+ error = debugger.GetTargetList().CreateTarget(
+ debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp);
+ if (error.Fail()) {
+ LLDB_LOG(log, "failed to create new target: {0}", error);
+ return process_sp;
+ }
+
+ target = new_target_sp.get();
+ if (!target) {
+ error.SetErrorString("CreateTarget() returned nullptr");
+ LLDB_LOG(log, "error: {0}", error);
+ return process_sp;
+ }
}
+
+ // Now create the gdb-remote process.
+ LLDB_LOG(log, "having target create process with gdb-remote plugin");
+ process_sp =
+ target->CreateProcess(launch_info.GetListener(), "gdb-remote", nullptr,
+ true);
+
+ if (!process_sp) {
+ error.SetErrorString("CreateProcess() failed for gdb-remote process");
+ LLDB_LOG(log, "error: {0}", error);
+ return process_sp;
+ }
+
+ LLDB_LOG(log, "successfully created process");
+ // Adjust launch for a hijacker.
+ ListenerSP listener_sp;
+ if (!launch_info.GetHijackListener()) {
+ LLDB_LOG(log, "setting up hijacker");
+ listener_sp =
+ Listener::MakeListener("lldb.PlatformLinux.DebugProcess.hijack");
+ launch_info.SetHijackListener(listener_sp);
+ process_sp->HijackProcessEvents(listener_sp);
+ }
+
+ // Log file actions.
+ if (log) {
+ LLDB_LOG(log, "launching process with the following file actions:");
+ StreamString stream;
+ size_t i = 0;
+ const FileAction *file_action;
+ while ((file_action = launch_info.GetFileActionAtIndex(i++)) != nullptr) {
+ file_action->Dump(stream);
+ LLDB_LOG(log, "{0}", stream.GetData());
+ stream.Clear();
+ }
+ }
+
+ // Do the launch.
+ error = process_sp->Launch(launch_info);
+ if (error.Success()) {
+ // Handle the hijacking of process events.
+ if (listener_sp) {
+ const StateType state = process_sp->WaitForProcessToStop(
+ llvm::None, nullptr, false, listener_sp);
+
+ LLDB_LOG(log, "pid {0} state {0}", process_sp->GetID(), state);
+ }
+
+ // Hook up process PTY if we have one (which we should for local debugging
+ // with llgs).
+ int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor();
+ if (pty_fd != PseudoTerminal::invalid_fd) {
+ process_sp->SetSTDIOFileDescriptor(pty_fd);
+ LLDB_LOG(log, "hooked up STDIO pty to process");
+ } else
+ LLDB_LOG(log, "not using process STDIO pty");
+ } else {
+ LLDB_LOG(log, "{0}", error);
+ // FIXME figure out appropriate cleanup here. Do we delete the target? Do
+ // we delete the process? Does our caller do that?
+ }
+
return process_sp;
}
@@ -540,30 +628,26 @@ PlatformPOSIX::MakeLoadImageUtilityFunction(ExecutionContext &exe_ctx,
expr.append(dlopen_wrapper_code);
Status utility_error;
DiagnosticManager diagnostics;
-
- std::unique_ptr<UtilityFunction> dlopen_utility_func_up(process
- ->GetTarget().GetUtilityFunctionForLanguage(expr.c_str(),
- eLanguageTypeObjC,
- dlopen_wrapper_name,
- utility_error));
- if (utility_error.Fail()) {
- error.SetErrorStringWithFormat("dlopen error: could not make utility"
- "function: %s", utility_error.AsCString());
- return nullptr;
- }
- if (!dlopen_utility_func_up->Install(diagnostics, exe_ctx)) {
- error.SetErrorStringWithFormat("dlopen error: could not install utility"
- "function: %s",
- diagnostics.GetString().c_str());
+
+ auto utility_fn_or_error = process->GetTarget().CreateUtilityFunction(
+ std::move(expr), dlopen_wrapper_name, eLanguageTypeObjC, exe_ctx);
+ if (!utility_fn_or_error) {
+ std::string error_str = llvm::toString(utility_fn_or_error.takeError());
+ error.SetErrorStringWithFormat("dlopen error: could not create utility"
+ "function: %s",
+ error_str.c_str());
return nullptr;
}
+ std::unique_ptr<UtilityFunction> dlopen_utility_func_up =
+ std::move(*utility_fn_or_error);
Value value;
ValueList arguments;
FunctionCaller *do_dlopen_function = nullptr;
// Fetch the clang types we will need:
- TypeSystemClang *ast = TypeSystemClang::GetScratch(process->GetTarget());
+ TypeSystemClang *ast =
+ ScratchTypeSystemClang::GetForTarget(process->GetTarget());
if (!ast)
return nullptr;
@@ -807,7 +891,8 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
Value return_value;
// Fetch the clang types we will need:
- TypeSystemClang *ast = TypeSystemClang::GetScratch(process->GetTarget());
+ TypeSystemClang *ast =
+ ScratchTypeSystemClang::GetForTarget(process->GetTarget());
if (!ast) {
error.SetErrorString("dlopen error: Unable to get TypeSystemClang");
return LLDB_INVALID_IMAGE_TOKEN;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 21bf7f4ac46d..6a4275d249f6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -495,12 +495,10 @@ lldb::ProcessSP PlatformRemoteGDBServer::DebugProcess(
error.Clear();
if (target && error.Success()) {
- debugger.GetTargetList().SetSelectedTarget(target);
-
// The darwin always currently uses the GDB remote debugger plug-in
// so even when debugging locally we are debugging remotely!
process_sp = target->CreateProcess(launch_info.GetListener(),
- "gdb-remote", nullptr);
+ "gdb-remote", nullptr, true);
if (process_sp) {
error = process_sp->ConnectRemote(connect_url.c_str());
@@ -581,13 +579,11 @@ lldb::ProcessSP PlatformRemoteGDBServer::Attach(
error.Clear();
if (target && error.Success()) {
- debugger.GetTargetList().SetSelectedTarget(target);
-
// The darwin always currently uses the GDB remote debugger plug-in
// so even when debugging locally we are debugging remotely!
process_sp =
target->CreateProcess(attach_info.GetListenerForProcess(debugger),
- "gdb-remote", nullptr);
+ "gdb-remote", nullptr, true);
if (process_sp) {
error = process_sp->ConnectRemote(connect_url.c_str());
if (error.Success()) {
@@ -661,6 +657,11 @@ PlatformRemoteGDBServer::GetFileSize(const FileSpec &file_spec) {
return m_gdb_client.GetFileSize(file_spec);
}
+void PlatformRemoteGDBServer::AutoCompleteDiskFileOrDirectory(
+ CompletionRequest &request, bool only_dir) {
+ m_gdb_client.AutoCompleteDiskFileOrDirectory(request, only_dir);
+}
+
uint64_t PlatformRemoteGDBServer::ReadFile(lldb::user_id_t fd, uint64_t offset,
void *dst, uint64_t dst_len,
Status &error) {
@@ -706,7 +707,7 @@ bool PlatformRemoteGDBServer::GetFileExists(const FileSpec &file_spec) {
}
Status PlatformRemoteGDBServer::RunShellCommand(
- const char *command, // Shouldn't be NULL
+ llvm::StringRef shell, llvm::StringRef command,
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
@@ -824,7 +825,7 @@ std::string PlatformRemoteGDBServer::MakeUrl(const char *scheme,
const char *hostname,
uint16_t port, const char *path) {
StreamString result;
- result.Printf("%s://%s", scheme, hostname);
+ result.Printf("%s://[%s]", scheme, hostname);
if (port != 0)
result.Printf(":%u", port);
if (path)
@@ -832,18 +833,6 @@ std::string PlatformRemoteGDBServer::MakeUrl(const char *scheme,
return std::string(result.GetString());
}
-lldb::ProcessSP PlatformRemoteGDBServer::ConnectProcess(
- llvm::StringRef connect_url, llvm::StringRef plugin_name,
- lldb_private::Debugger &debugger, lldb_private::Target *target,
- lldb_private::Status &error) {
- if (!IsRemote() || !IsConnected()) {
- error.SetErrorString("Not connected to remote gdb server");
- return nullptr;
- }
- return Platform::ConnectProcess(connect_url, plugin_name, debugger, target,
- error);
-}
-
size_t PlatformRemoteGDBServer::ConnectToWaitingProcesses(Debugger &debugger,
Status &error) {
std::vector<std::string> connection_urls;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index 0602be1fa377..e43cd0e55c6d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -127,6 +127,9 @@ public:
lldb::user_id_t GetFileSize(const FileSpec &file_spec) override;
+ void AutoCompleteDiskFileOrDirectory(CompletionRequest &request,
+ bool only_dir) override;
+
Status PutFile(const FileSpec &source, const FileSpec &destination,
uint32_t uid = UINT32_MAX, uint32_t gid = UINT32_MAX) override;
@@ -137,7 +140,7 @@ public:
Status Unlink(const FileSpec &path) override;
Status RunShellCommand(
- const char *command, // Shouldn't be NULL
+ llvm::StringRef shell, llvm::StringRef command,
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
@@ -151,12 +154,6 @@ public:
const lldb::UnixSignalsSP &GetRemoteUnixSignals() override;
- lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url,
- llvm::StringRef plugin_name,
- lldb_private::Debugger &debugger,
- lldb_private::Target *target,
- lldb_private::Status &error) override;
-
size_t ConnectToWaitingProcesses(lldb_private::Debugger &debugger,
lldb_private::Status &error) override;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
deleted file mode 100644
index 896f68eadfe1..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
+++ /dev/null
@@ -1,616 +0,0 @@
-//===-- FreeBSDThread.cpp -------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include <errno.h>
-#include <pthread.h>
-#include <pthread_np.h>
-#include <stdlib.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-#include <sys/user.h>
-
-#include "FreeBSDThread.h"
-#include "POSIXStopInfo.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
-#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
-#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
-#include "ProcessFreeBSD.h"
-#include "ProcessMonitor.h"
-#include "RegisterContextPOSIXProcessMonitor_arm.h"
-#include "RegisterContextPOSIXProcessMonitor_arm64.h"
-#include "RegisterContextPOSIXProcessMonitor_mips64.h"
-#include "RegisterContextPOSIXProcessMonitor_powerpc.h"
-#include "RegisterContextPOSIXProcessMonitor_x86.h"
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/HostNativeThread.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/StopInfo.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/ThreadSpec.h"
-#include "lldb/Target/UnixSignals.h"
-#include "lldb/Target/Unwind.h"
-#include "lldb/Utility/State.h"
-#include "llvm/ADT/SmallString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-FreeBSDThread::FreeBSDThread(Process &process, lldb::tid_t tid)
- : Thread(process, tid), m_frame_up(), m_breakpoint(),
- m_thread_name_valid(false), m_thread_name(), m_posix_thread(nullptr) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
- LLDB_LOGV(log, "tid = {0}", tid);
-
- // Set the current watchpoints for this thread.
- Target &target = GetProcess()->GetTarget();
- const WatchpointList &wp_list = target.GetWatchpointList();
- size_t wp_size = wp_list.GetSize();
-
- for (uint32_t wp_idx = 0; wp_idx < wp_size; wp_idx++) {
- lldb::WatchpointSP wp = wp_list.GetByIndex(wp_idx);
- if (wp.get() && wp->IsEnabled()) {
- // This watchpoint as been enabled; obviously this "new" thread has been
- // created since that watchpoint was enabled. Since the
- // POSIXBreakpointProtocol has yet to be initialized, its
- // m_watchpoints_initialized member will be FALSE. Attempting to read
- // the debug status register to determine if a watchpoint has been hit
- // would result in the zeroing of that register. Since the active debug
- // registers would have been cloned when this thread was created, simply
- // force the m_watchpoints_initized member to TRUE and avoid resetting
- // dr6 and dr7.
- GetPOSIXBreakpointProtocol()->ForceWatchpointsInitialized();
- }
- }
-}
-
-FreeBSDThread::~FreeBSDThread() { DestroyThread(); }
-
-ProcessMonitor &FreeBSDThread::GetMonitor() {
- ProcessSP base = GetProcess();
- ProcessFreeBSD &process = static_cast<ProcessFreeBSD &>(*base);
- return process.GetMonitor();
-}
-
-void FreeBSDThread::RefreshStateAfterStop() {
- // Invalidate all registers in our register context. We don't set "force" to
- // true because the stop reply packet might have had some register values
- // that were expedited and these will already be copied into the register
- // context by the time this function gets called. The KDPRegisterContext
- // class has been made smart enough to detect when it needs to invalidate
- // which registers are valid by putting hooks in the register read and
- // register supply functions where they check the process stop ID and do the
- // right thing. if (StateIsStoppedState(GetState())
- {
- const bool force = false;
- GetRegisterContext()->InvalidateIfNeeded(force);
- }
-}
-
-const char *FreeBSDThread::GetInfo() { return nullptr; }
-
-void FreeBSDThread::SetName(const char *name) {
- m_thread_name_valid = (name && name[0]);
- if (m_thread_name_valid)
- m_thread_name.assign(name);
- else
- m_thread_name.clear();
-}
-
-const char *FreeBSDThread::GetName() {
- if (!m_thread_name_valid) {
- m_thread_name.clear();
- int pid = GetProcess()->GetID();
-
- struct kinfo_proc *kp = nullptr, *nkp;
- size_t len = 0;
- int error;
- int ctl[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD,
- pid};
-
- while (1) {
- error = sysctl(ctl, 4, kp, &len, nullptr, 0);
- if (kp == nullptr || (error != 0 && errno == ENOMEM)) {
- // Add extra space in case threads are added before next call.
- len += sizeof(*kp) + len / 10;
- nkp = (struct kinfo_proc *)realloc(kp, len);
- if (nkp == nullptr) {
- free(kp);
- return nullptr;
- }
- kp = nkp;
- continue;
- }
- if (error != 0)
- len = 0;
- break;
- }
-
- for (size_t i = 0; i < len / sizeof(*kp); i++) {
- if (kp[i].ki_tid == (lwpid_t)GetID()) {
- m_thread_name.append(kp[i].ki_tdname,
- kp[i].ki_tdname + strlen(kp[i].ki_tdname));
- break;
- }
- }
- free(kp);
- m_thread_name_valid = true;
- }
-
- if (m_thread_name.empty())
- return nullptr;
- return m_thread_name.c_str();
-}
-
-lldb::RegisterContextSP FreeBSDThread::GetRegisterContext() {
- if (!m_reg_context_sp) {
- m_posix_thread = nullptr;
-
- RegisterInfoInterface *reg_interface = nullptr;
- const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture();
-
- switch (target_arch.GetMachine()) {
- case llvm::Triple::aarch64:
- break;
- case llvm::Triple::arm:
- reg_interface = new RegisterInfoPOSIX_arm(target_arch);
- break;
- case llvm::Triple::ppc:
-#ifndef __powerpc64__
- reg_interface = new RegisterContextFreeBSD_powerpc32(target_arch);
- break;
-#endif
- case llvm::Triple::ppc64:
- reg_interface = new RegisterContextFreeBSD_powerpc64(target_arch);
- break;
- case llvm::Triple::mips64:
- reg_interface = new RegisterContextFreeBSD_mips64(target_arch);
- break;
- case llvm::Triple::x86:
- reg_interface = new RegisterContextFreeBSD_i386(target_arch);
- break;
- case llvm::Triple::x86_64:
- reg_interface = new RegisterContextFreeBSD_x86_64(target_arch);
- break;
- default:
- llvm_unreachable("CPU not supported");
- }
-
- switch (target_arch.GetMachine()) {
- case llvm::Triple::aarch64: {
- RegisterContextPOSIXProcessMonitor_arm64 *reg_ctx =
- new RegisterContextPOSIXProcessMonitor_arm64(
- *this, std::make_unique<RegisterInfoPOSIX_arm64>(target_arch));
- m_posix_thread = reg_ctx;
- m_reg_context_sp.reset(reg_ctx);
- break;
- }
- case llvm::Triple::arm: {
- RegisterContextPOSIXProcessMonitor_arm *reg_ctx =
- new RegisterContextPOSIXProcessMonitor_arm(*this, 0, reg_interface);
- m_posix_thread = reg_ctx;
- m_reg_context_sp.reset(reg_ctx);
- break;
- }
- case llvm::Triple::mips64: {
- RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx =
- new RegisterContextPOSIXProcessMonitor_mips64(*this, 0,
- reg_interface);
- m_posix_thread = reg_ctx;
- m_reg_context_sp.reset(reg_ctx);
- break;
- }
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64: {
- RegisterContextPOSIXProcessMonitor_powerpc *reg_ctx =
- new RegisterContextPOSIXProcessMonitor_powerpc(*this, 0,
- reg_interface);
- m_posix_thread = reg_ctx;
- m_reg_context_sp.reset(reg_ctx);
- break;
- }
- case llvm::Triple::x86:
- case llvm::Triple::x86_64: {
- RegisterContextPOSIXProcessMonitor_x86_64 *reg_ctx =
- new RegisterContextPOSIXProcessMonitor_x86_64(*this, 0,
- reg_interface);
- m_posix_thread = reg_ctx;
- m_reg_context_sp.reset(reg_ctx);
- break;
- }
- default:
- break;
- }
- }
- return m_reg_context_sp;
-}
-
-lldb::RegisterContextSP
-FreeBSDThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) {
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t concrete_frame_idx = 0;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
- LLDB_LOGV(log, "called");
-
- if (frame)
- concrete_frame_idx = frame->GetConcreteFrameIndex();
-
- if (concrete_frame_idx == 0)
- reg_ctx_sp = GetRegisterContext();
- else {
- reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
- }
-
- return reg_ctx_sp;
-}
-
-lldb::addr_t FreeBSDThread::GetThreadPointer() {
- ProcessMonitor &monitor = GetMonitor();
- addr_t addr;
- if (monitor.ReadThreadPointer(GetID(), addr))
- return addr;
- else
- return LLDB_INVALID_ADDRESS;
-}
-
-bool FreeBSDThread::CalculateStopInfo() {
- SetStopInfo(m_stop_info_sp);
- return true;
-}
-
-void FreeBSDThread::DidStop() {
- // Don't set the thread state to stopped unless we really stopped.
-}
-
-void FreeBSDThread::WillResume(lldb::StateType resume_state) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
- LLDB_LOGF(log, "tid %" PRIu64 " resume_state = %s", GetID(),
- lldb_private::StateAsCString(resume_state));
- ProcessSP process_sp(GetProcess());
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(process_sp.get());
- int signo = GetResumeSignal();
- bool signo_valid = process->GetUnixSignals()->SignalIsValid(signo);
-
- switch (resume_state) {
- case eStateSuspended:
- case eStateStopped:
- process->m_suspend_tids.push_back(GetID());
- break;
- case eStateRunning:
- process->m_run_tids.push_back(GetID());
- if (signo_valid)
- process->m_resume_signo = signo;
- break;
- case eStateStepping:
- process->m_step_tids.push_back(GetID());
- if (signo_valid)
- process->m_resume_signo = signo;
- break;
- default:
- break;
- }
-}
-
-bool FreeBSDThread::Resume() {
- lldb::StateType resume_state = GetResumeState();
- ProcessMonitor &monitor = GetMonitor();
- bool status;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
- LLDB_LOGF(log, "FreeBSDThread::%s (), resume_state = %s", __FUNCTION__,
- StateAsCString(resume_state));
-
- switch (resume_state) {
- default:
- assert(false && "Unexpected state for resume!");
- status = false;
- break;
-
- case lldb::eStateRunning:
- SetState(resume_state);
- status = monitor.Resume(GetID(), GetResumeSignal());
- break;
-
- case lldb::eStateStepping:
- SetState(resume_state);
- status = monitor.SingleStep(GetID(), GetResumeSignal());
- break;
- case lldb::eStateStopped:
- case lldb::eStateSuspended:
- status = true;
- break;
- }
-
- return status;
-}
-
-void FreeBSDThread::Notify(const ProcessMessage &message) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
- LLDB_LOGF(log, "FreeBSDThread::%s () message kind = '%s' for tid %" PRIu64,
- __FUNCTION__, message.PrintKind(), GetID());
-
- switch (message.GetKind()) {
- default:
- assert(false && "Unexpected message kind!");
- break;
-
- case ProcessMessage::eExitMessage:
- // Nothing to be done.
- break;
-
- case ProcessMessage::eLimboMessage:
- LimboNotify(message);
- break;
-
- case ProcessMessage::eCrashMessage:
- case ProcessMessage::eSignalMessage:
- SignalNotify(message);
- break;
-
- case ProcessMessage::eSignalDeliveredMessage:
- SignalDeliveredNotify(message);
- break;
-
- case ProcessMessage::eTraceMessage:
- TraceNotify(message);
- break;
-
- case ProcessMessage::eBreakpointMessage:
- BreakNotify(message);
- break;
-
- case ProcessMessage::eWatchpointMessage:
- WatchNotify(message);
- break;
-
- case ProcessMessage::eExecMessage:
- ExecNotify(message);
- break;
- }
-}
-
-bool FreeBSDThread::EnableHardwareWatchpoint(Watchpoint *wp) {
- bool wp_set = false;
- if (wp) {
- addr_t wp_addr = wp->GetLoadAddress();
- size_t wp_size = wp->GetByteSize();
- bool wp_read = wp->WatchpointRead();
- bool wp_write = wp->WatchpointWrite();
- uint32_t wp_hw_index = wp->GetHardwareIndex();
- POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
- if (reg_ctx)
- wp_set = reg_ctx->SetHardwareWatchpointWithIndex(
- wp_addr, wp_size, wp_read, wp_write, wp_hw_index);
- }
- return wp_set;
-}
-
-bool FreeBSDThread::DisableHardwareWatchpoint(Watchpoint *wp) {
- bool result = false;
- if (wp) {
- lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
- if (reg_ctx_sp.get())
- result = reg_ctx_sp->ClearHardwareWatchpoint(wp->GetHardwareIndex());
- }
- return result;
-}
-
-uint32_t FreeBSDThread::NumSupportedHardwareWatchpoints() {
- lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
- if (reg_ctx_sp.get())
- return reg_ctx_sp->NumSupportedHardwareWatchpoints();
- return 0;
-}
-
-uint32_t FreeBSDThread::FindVacantWatchpointIndex() {
- uint32_t hw_index = LLDB_INVALID_INDEX32;
- uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
- uint32_t wp_idx;
- POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
- if (reg_ctx) {
- for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
- if (reg_ctx->IsWatchpointVacant(wp_idx)) {
- hw_index = wp_idx;
- break;
- }
- }
- }
- return hw_index;
-}
-
-void FreeBSDThread::BreakNotify(const ProcessMessage &message) {
- bool status;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
-
- assert(GetRegisterContext());
- status = GetPOSIXBreakpointProtocol()->UpdateAfterBreakpoint();
- assert(status && "Breakpoint update failed!");
-
- // With our register state restored, resolve the breakpoint object
- // corresponding to our current PC.
- assert(GetRegisterContext());
- lldb::addr_t pc = GetRegisterContext()->GetPC();
- LLDB_LOGF(log, "FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
- lldb::BreakpointSiteSP bp_site(
- GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
-
- // If the breakpoint is for this thread, then we'll report the hit, but if it
- // is for another thread, we create a stop reason with should_stop=false. If
- // there is no breakpoint location, then report an invalid stop reason. We
- // don't need to worry about stepping over the breakpoint here, that will be
- // taken care of when the thread resumes and notices that there's a
- // breakpoint under the pc.
- if (bp_site) {
- lldb::break_id_t bp_id = bp_site->GetID();
- // 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->ValidForThisThread(this) ||
- GetProcess()->GetOperatingSystem() != nullptr)
- SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id));
- else {
- const bool should_stop = false;
- SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id,
- should_stop));
- }
- } else
- SetStopInfo(StopInfoSP());
-}
-
-void FreeBSDThread::WatchNotify(const ProcessMessage &message) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
-
- lldb::addr_t halt_addr = message.GetHWAddress();
- LLDB_LOGF(log,
- "FreeBSDThread::%s () Hardware Watchpoint Address = 0x%8.8" PRIx64,
- __FUNCTION__, halt_addr);
-
- POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
- if (reg_ctx) {
- uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
- uint32_t wp_idx;
- for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
- if (reg_ctx->IsWatchpointHit(wp_idx)) {
- // Clear the watchpoint hit here
- reg_ctx->ClearWatchpointHits();
- break;
- }
- }
-
- if (wp_idx == num_hw_wps)
- return;
-
- Target &target = GetProcess()->GetTarget();
- lldb::addr_t wp_monitor_addr = reg_ctx->GetWatchpointAddress(wp_idx);
- const WatchpointList &wp_list = target.GetWatchpointList();
- lldb::WatchpointSP wp_sp = wp_list.FindByAddress(wp_monitor_addr);
-
- assert(wp_sp.get() && "No watchpoint found");
- SetStopInfo(
- StopInfo::CreateStopReasonWithWatchpointID(*this, wp_sp->GetID()));
- }
-}
-
-void FreeBSDThread::TraceNotify(const ProcessMessage &message) {
- 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();
- LLDB_LOGF(log, "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() != nullptr))
- SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(
- *this, bp_site->GetID()));
- else {
- POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
- if (reg_ctx) {
- uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
- uint32_t wp_idx;
- for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
- if (reg_ctx->IsWatchpointHit(wp_idx)) {
- WatchNotify(message);
- return;
- }
- }
- }
- SetStopInfo(StopInfo::CreateStopReasonToTrace(*this));
- }
-}
-
-void FreeBSDThread::LimboNotify(const ProcessMessage &message) {
- SetStopInfo(lldb::StopInfoSP(new POSIXLimboStopInfo(*this)));
-}
-
-void FreeBSDThread::SignalNotify(const ProcessMessage &message) {
- int signo = message.GetSignal();
- if (message.GetKind() == ProcessMessage::eCrashMessage) {
- std::string stop_description = GetCrashReasonString(
- message.GetCrashReason(), message.GetFaultAddress());
- SetStopInfo(StopInfo::CreateStopReasonWithSignal(
- *this, signo, stop_description.c_str()));
- } else {
- SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
- }
-}
-
-void FreeBSDThread::SignalDeliveredNotify(const ProcessMessage &message) {
- int signo = message.GetSignal();
- SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
-}
-
-unsigned FreeBSDThread::GetRegisterIndexFromOffset(unsigned offset) {
- unsigned reg = LLDB_INVALID_REGNUM;
- ArchSpec arch = HostInfo::GetArchitecture();
-
- switch (arch.GetMachine()) {
- default:
- llvm_unreachable("CPU type not supported!");
- break;
-
- case llvm::Triple::aarch64:
- case llvm::Triple::arm:
- case llvm::Triple::mips64:
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- case llvm::Triple::x86:
- case llvm::Triple::x86_64: {
- POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
- reg = reg_ctx->GetRegisterIndexFromOffset(offset);
- } break;
- }
- return reg;
-}
-
-void FreeBSDThread::ExecNotify(const ProcessMessage &message) {
- SetStopInfo(StopInfo::CreateStopReasonWithExec(*this));
-}
-
-const char *FreeBSDThread::GetRegisterName(unsigned reg) {
- const char *name = nullptr;
- ArchSpec arch = HostInfo::GetArchitecture();
-
- switch (arch.GetMachine()) {
- default:
- assert(false && "CPU type not supported!");
- break;
-
- case llvm::Triple::aarch64:
- case llvm::Triple::arm:
- case llvm::Triple::mips64:
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- name = GetRegisterContext()->GetRegisterName(reg);
- break;
- }
- return name;
-}
-
-const char *FreeBSDThread::GetRegisterNameFromOffset(unsigned offset) {
- return GetRegisterName(GetRegisterIndexFromOffset(offset));
-}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h
deleted file mode 100644
index 774ffb511bc6..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h
+++ /dev/null
@@ -1,111 +0,0 @@
-//===-- FreeBSDThread.h -----------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_FreeBSDThread_H_
-#define liblldb_FreeBSDThread_H_
-
-#include <memory>
-#include <string>
-
-#include "RegisterContextPOSIX.h"
-#include "lldb/Target/Thread.h"
-
-class ProcessMessage;
-class ProcessMonitor;
-class POSIXBreakpointProtocol;
-
-// @class FreeBSDThread
-// Abstraction of a FreeBSD thread.
-class FreeBSDThread : public lldb_private::Thread {
-public:
- // Constructors and destructors
- FreeBSDThread(lldb_private::Process &process, lldb::tid_t tid);
-
- virtual ~FreeBSDThread();
-
- // POSIXThread
- void RefreshStateAfterStop() override;
-
- // This notifies the thread when a private stop occurs.
- void DidStop() override;
-
- const char *GetInfo() override;
-
- void SetName(const char *name) override;
-
- const char *GetName() override;
-
- lldb::RegisterContextSP GetRegisterContext() override;
-
- lldb::RegisterContextSP
- CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
-
- lldb::addr_t GetThreadPointer() override;
-
- // These functions provide a mapping from the register offset
- // back to the register index or name for use in debugging or log
- // output.
-
- unsigned GetRegisterIndexFromOffset(unsigned offset);
-
- const char *GetRegisterName(unsigned reg);
-
- const char *GetRegisterNameFromOffset(unsigned offset);
-
- // These methods form a specialized interface to POSIX threads.
- //
- bool Resume();
-
- void Notify(const ProcessMessage &message);
-
- // These methods provide an interface to watchpoints
- //
- bool EnableHardwareWatchpoint(lldb_private::Watchpoint *wp);
-
- bool DisableHardwareWatchpoint(lldb_private::Watchpoint *wp);
-
- uint32_t NumSupportedHardwareWatchpoints();
-
- uint32_t FindVacantWatchpointIndex();
-
-protected:
- POSIXBreakpointProtocol *GetPOSIXBreakpointProtocol() {
- if (!m_reg_context_sp)
- m_reg_context_sp = GetRegisterContext();
- return m_posix_thread;
- }
-
- std::unique_ptr<lldb_private::StackFrame> m_frame_up;
-
- lldb::BreakpointSiteSP m_breakpoint;
-
- bool m_thread_name_valid;
- std::string m_thread_name;
- POSIXBreakpointProtocol *m_posix_thread;
-
- ProcessMonitor &GetMonitor();
-
- bool CalculateStopInfo() override;
-
- void BreakNotify(const ProcessMessage &message);
- void WatchNotify(const ProcessMessage &message);
- virtual void TraceNotify(const ProcessMessage &message);
- void LimboNotify(const ProcessMessage &message);
- void SignalNotify(const ProcessMessage &message);
- void SignalDeliveredNotify(const ProcessMessage &message);
- void CrashNotify(const ProcessMessage &message);
- void ExitNotify(const ProcessMessage &message);
- void ExecNotify(const ProcessMessage &message);
-
- // FreeBSDThread internal API.
-
- // POSIXThread override
- virtual void WillResume(lldb::StateType resume_state) override;
-};
-
-#endif // #ifndef liblldb_FreeBSDThread_H_
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
new file mode 100644
index 000000000000..5961ff4439db
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
@@ -0,0 +1,921 @@
+//===-- NativeProcessFreeBSD.cpp ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeProcessFreeBSD.h"
+
+// clang-format off
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/sysctl.h>
+#include <sys/user.h>
+#include <sys/wait.h>
+#include <machine/elf.h>
+// clang-format on
+
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/State.h"
+#include "llvm/Support/Errno.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_freebsd;
+using namespace llvm;
+
+// Simple helper function to ensure flags are enabled on the given file
+// descriptor.
+static Status EnsureFDFlags(int fd, int flags) {
+ Status error;
+
+ int status = fcntl(fd, F_GETFL);
+ if (status == -1) {
+ error.SetErrorToErrno();
+ return error;
+ }
+
+ if (fcntl(fd, F_SETFL, status | flags) == -1) {
+ error.SetErrorToErrno();
+ return error;
+ }
+
+ return error;
+}
+
+// Public Static Methods
+
+llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
+NativeProcessFreeBSD::Factory::Launch(ProcessLaunchInfo &launch_info,
+ NativeDelegate &native_delegate,
+ MainLoop &mainloop) const {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+
+ Status status;
+ ::pid_t pid = ProcessLauncherPosixFork()
+ .LaunchProcess(launch_info, status)
+ .GetProcessId();
+ LLDB_LOG(log, "pid = {0:x}", pid);
+ if (status.Fail()) {
+ LLDB_LOG(log, "failed to launch process: {0}", status);
+ return status.ToError();
+ }
+
+ // Wait for the child process to trap on its call to execve.
+ int wstatus;
+ ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
+ assert(wpid == pid);
+ (void)wpid;
+ if (!WIFSTOPPED(wstatus)) {
+ LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
+ WaitStatus::Decode(wstatus));
+ return llvm::make_error<StringError>("Could not sync with inferior process",
+ llvm::inconvertibleErrorCode());
+ }
+ LLDB_LOG(log, "inferior started, now in stopped state");
+
+ ProcessInstanceInfo Info;
+ if (!Host::GetProcessInfo(pid, Info)) {
+ return llvm::make_error<StringError>("Cannot get process architecture",
+ llvm::inconvertibleErrorCode());
+ }
+
+ // Set the architecture to the exe architecture.
+ LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
+ Info.GetArchitecture().GetArchitectureName());
+
+ std::unique_ptr<NativeProcessFreeBSD> process_up(new NativeProcessFreeBSD(
+ pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate,
+ Info.GetArchitecture(), mainloop));
+
+ status = process_up->SetupTrace();
+ if (status.Fail())
+ return status.ToError();
+
+ for (const auto &thread : process_up->m_threads)
+ static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
+ process_up->SetState(StateType::eStateStopped, false);
+
+ return std::move(process_up);
+}
+
+llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
+NativeProcessFreeBSD::Factory::Attach(
+ lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
+ MainLoop &mainloop) const {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ LLDB_LOG(log, "pid = {0:x}", pid);
+
+ // Retrieve the architecture for the running process.
+ ProcessInstanceInfo Info;
+ if (!Host::GetProcessInfo(pid, Info)) {
+ return llvm::make_error<StringError>("Cannot get process architecture",
+ llvm::inconvertibleErrorCode());
+ }
+
+ std::unique_ptr<NativeProcessFreeBSD> process_up(new NativeProcessFreeBSD(
+ pid, -1, native_delegate, Info.GetArchitecture(), mainloop));
+
+ Status status = process_up->Attach();
+ if (!status.Success())
+ return status.ToError();
+
+ return std::move(process_up);
+}
+
+// Public Instance Methods
+
+NativeProcessFreeBSD::NativeProcessFreeBSD(::pid_t pid, int terminal_fd,
+ NativeDelegate &delegate,
+ const ArchSpec &arch,
+ MainLoop &mainloop)
+ : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch) {
+ if (m_terminal_fd != -1) {
+ Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
+ assert(status.Success());
+ }
+
+ Status status;
+ m_sigchld_handle = mainloop.RegisterSignal(
+ SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
+ assert(m_sigchld_handle && status.Success());
+}
+
+// Handles all waitpid events from the inferior process.
+void NativeProcessFreeBSD::MonitorCallback(lldb::pid_t pid, int signal) {
+ switch (signal) {
+ case SIGTRAP:
+ return MonitorSIGTRAP(pid);
+ case SIGSTOP:
+ return MonitorSIGSTOP(pid);
+ default:
+ return MonitorSignal(pid, signal);
+ }
+}
+
+void NativeProcessFreeBSD::MonitorExited(lldb::pid_t pid, WaitStatus status) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+
+ LLDB_LOG(log, "got exit signal({0}) , pid = {1}", status, pid);
+
+ /* Stop Tracking All Threads attached to Process */
+ m_threads.clear();
+
+ SetExitStatus(status, true);
+
+ // Notify delegate that our process has exited.
+ SetState(StateType::eStateExited, true);
+}
+
+void NativeProcessFreeBSD::MonitorSIGSTOP(lldb::pid_t pid) {
+ /* Stop all Threads attached to Process */
+ for (const auto &thread : m_threads) {
+ static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedBySignal(SIGSTOP,
+ nullptr);
+ }
+ SetState(StateType::eStateStopped, true);
+}
+
+void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ struct ptrace_lwpinfo info;
+
+ const auto siginfo_err = PtraceWrapper(PT_LWPINFO, pid, &info, sizeof(info));
+ if (siginfo_err.Fail()) {
+ LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err);
+ return;
+ }
+ assert(info.pl_event == PL_EVENT_SIGNAL);
+
+ LLDB_LOG(log, "got SIGTRAP, pid = {0}, lwpid = {1}, flags = {2:x}", pid,
+ info.pl_lwpid, info.pl_flags);
+ NativeThreadFreeBSD *thread = nullptr;
+
+ if (info.pl_flags & (PL_FLAG_BORN | PL_FLAG_EXITED)) {
+ if (info.pl_flags & PL_FLAG_BORN) {
+ LLDB_LOG(log, "monitoring new thread, tid = {0}", info.pl_lwpid);
+ NativeThreadFreeBSD &t = AddThread(info.pl_lwpid);
+
+ // Technically, the FreeBSD kernel copies the debug registers to new
+ // threads. However, there is a non-negligible delay between acquiring
+ // the DR values and reporting the new thread during which the user may
+ // establish a new watchpoint. In order to ensure that watchpoints
+ // established during this period are propagated to new threads,
+ // explicitly copy the DR value at the time the new thread is reported.
+ //
+ // See also: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=250954
+
+ llvm::Error error = t.CopyWatchpointsFrom(
+ static_cast<NativeThreadFreeBSD &>(*GetCurrentThread()));
+ if (error) {
+ LLDB_LOG_ERROR(log, std::move(error),
+ "failed to copy watchpoints to new thread {1}: {0}",
+ info.pl_lwpid);
+ SetState(StateType::eStateInvalid);
+ return;
+ }
+ } else /*if (info.pl_flags & PL_FLAG_EXITED)*/ {
+ LLDB_LOG(log, "thread exited, tid = {0}", info.pl_lwpid);
+ RemoveThread(info.pl_lwpid);
+ }
+
+ Status error =
+ PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0);
+ if (error.Fail())
+ SetState(StateType::eStateInvalid);
+ return;
+ }
+
+ if (info.pl_flags & PL_FLAG_EXEC) {
+ Status error = ReinitializeThreads();
+ if (error.Fail()) {
+ SetState(StateType::eStateInvalid);
+ return;
+ }
+
+ // Let our delegate know we have just exec'd.
+ NotifyDidExec();
+
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedByExec();
+ SetState(StateType::eStateStopped, true);
+ return;
+ }
+
+ if (info.pl_lwpid > 0) {
+ for (const auto &t : m_threads) {
+ if (t->GetID() == static_cast<lldb::tid_t>(info.pl_lwpid))
+ thread = static_cast<NativeThreadFreeBSD *>(t.get());
+ static_cast<NativeThreadFreeBSD *>(t.get())->SetStoppedWithNoReason();
+ }
+ if (!thread)
+ LLDB_LOG(log, "thread not found in m_threads, pid = {0}, LWP = {1}", pid,
+ info.pl_lwpid);
+ }
+
+ if (info.pl_flags & PL_FLAG_SI) {
+ assert(info.pl_siginfo.si_signo == SIGTRAP);
+ LLDB_LOG(log, "SIGTRAP siginfo: si_code = {0}, pid = {1}",
+ info.pl_siginfo.si_code, info.pl_siginfo.si_pid);
+
+ switch (info.pl_siginfo.si_code) {
+ case TRAP_BRKPT:
+ LLDB_LOG(log, "SIGTRAP/TRAP_BRKPT: si_addr: {0}",
+ info.pl_siginfo.si_addr);
+
+ if (thread) {
+ auto thread_info =
+ m_threads_stepping_with_breakpoint.find(thread->GetID());
+ if (thread_info != m_threads_stepping_with_breakpoint.end()) {
+ thread->SetStoppedByTrace();
+ Status brkpt_error = RemoveBreakpoint(thread_info->second);
+ if (brkpt_error.Fail())
+ LLDB_LOG(log, "pid = {0} remove stepping breakpoint: {1}",
+ thread_info->first, brkpt_error);
+ m_threads_stepping_with_breakpoint.erase(thread_info);
+ } else
+ thread->SetStoppedByBreakpoint();
+ FixupBreakpointPCAsNeeded(*thread);
+ }
+ SetState(StateType::eStateStopped, true);
+ return;
+ case TRAP_TRACE:
+ LLDB_LOG(log, "SIGTRAP/TRAP_TRACE: si_addr: {0}",
+ info.pl_siginfo.si_addr);
+
+ if (thread) {
+ auto &regctx = static_cast<NativeRegisterContextFreeBSD &>(
+ thread->GetRegisterContext());
+ uint32_t wp_index = LLDB_INVALID_INDEX32;
+ Status error = regctx.GetWatchpointHitIndex(
+ wp_index, reinterpret_cast<uintptr_t>(info.pl_siginfo.si_addr));
+ if (error.Fail())
+ LLDB_LOG(log,
+ "received error while checking for watchpoint hits, pid = "
+ "{0}, LWP = {1}, error = {2}",
+ pid, info.pl_lwpid, error);
+ if (wp_index != LLDB_INVALID_INDEX32) {
+ regctx.ClearWatchpointHit(wp_index);
+ thread->SetStoppedByWatchpoint(wp_index);
+ SetState(StateType::eStateStopped, true);
+ break;
+ }
+
+ thread->SetStoppedByTrace();
+ }
+
+ SetState(StateType::eStateStopped, true);
+ return;
+ }
+ }
+
+ // Either user-generated SIGTRAP or an unknown event that would
+ // otherwise leave the debugger hanging.
+ LLDB_LOG(log, "unknown SIGTRAP, passing to generic handler");
+ MonitorSignal(pid, SIGTRAP);
+}
+
+void NativeProcessFreeBSD::MonitorSignal(lldb::pid_t pid, int signal) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ struct ptrace_lwpinfo info;
+
+ const auto siginfo_err = PtraceWrapper(PT_LWPINFO, pid, &info, sizeof(info));
+ if (siginfo_err.Fail()) {
+ LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err);
+ return;
+ }
+ assert(info.pl_event == PL_EVENT_SIGNAL);
+ // TODO: do we need to handle !PL_FLAG_SI?
+ assert(info.pl_flags & PL_FLAG_SI);
+ assert(info.pl_siginfo.si_signo == signal);
+
+ for (const auto &abs_thread : m_threads) {
+ NativeThreadFreeBSD &thread =
+ static_cast<NativeThreadFreeBSD &>(*abs_thread);
+ assert(info.pl_lwpid >= 0);
+ if (info.pl_lwpid == 0 ||
+ static_cast<lldb::tid_t>(info.pl_lwpid) == thread.GetID())
+ thread.SetStoppedBySignal(info.pl_siginfo.si_signo, &info.pl_siginfo);
+ else
+ thread.SetStoppedWithNoReason();
+ }
+ SetState(StateType::eStateStopped, true);
+}
+
+Status NativeProcessFreeBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr,
+ int data, int *result) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
+ Status error;
+ int ret;
+
+ errno = 0;
+ ret =
+ ptrace(req, static_cast<::pid_t>(pid), static_cast<caddr_t>(addr), data);
+
+ if (ret == -1)
+ error.SetErrorToErrno();
+
+ if (result)
+ *result = ret;
+
+ LLDB_LOG(log, "ptrace({0}, {1}, {2}, {3})={4:x}", req, pid, addr, data, ret);
+
+ if (error.Fail())
+ LLDB_LOG(log, "ptrace() failed: {0}", error);
+
+ return error;
+}
+
+llvm::Expected<llvm::ArrayRef<uint8_t>>
+NativeProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
+ static const uint8_t g_arm_opcode[] = {0xfe, 0xde, 0xff, 0xe7};
+ static const uint8_t g_thumb_opcode[] = {0x01, 0xde};
+
+ switch (GetArchitecture().GetMachine()) {
+ case llvm::Triple::arm:
+ switch (size_hint) {
+ case 2:
+ return llvm::makeArrayRef(g_thumb_opcode);
+ case 4:
+ return llvm::makeArrayRef(g_arm_opcode);
+ default:
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Unrecognised trap opcode size hint!");
+ }
+ default:
+ return NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_hint);
+ }
+}
+
+Status NativeProcessFreeBSD::Resume(const ResumeActionList &resume_actions) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ LLDB_LOG(log, "pid {0}", GetID());
+
+ Status ret;
+
+ int signal = 0;
+ for (const auto &abs_thread : m_threads) {
+ assert(abs_thread && "thread list should not contain NULL threads");
+ NativeThreadFreeBSD &thread =
+ static_cast<NativeThreadFreeBSD &>(*abs_thread);
+
+ const ResumeAction *action =
+ resume_actions.GetActionForThread(thread.GetID(), true);
+ // we need to explicit issue suspend requests, so it is simpler to map it
+ // into proper action
+ ResumeAction suspend_action{thread.GetID(), eStateSuspended,
+ LLDB_INVALID_SIGNAL_NUMBER};
+
+ if (action == nullptr) {
+ LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),
+ thread.GetID());
+ action = &suspend_action;
+ }
+
+ LLDB_LOG(
+ log,
+ "processing resume action state {0} signal {1} for pid {2} tid {3}",
+ action->state, action->signal, GetID(), thread.GetID());
+
+ switch (action->state) {
+ case eStateRunning:
+ ret = thread.Resume();
+ break;
+ case eStateStepping:
+ ret = thread.SingleStep();
+ break;
+ case eStateSuspended:
+ case eStateStopped:
+ if (action->signal != LLDB_INVALID_SIGNAL_NUMBER)
+ return Status("Passing signal to suspended thread unsupported");
+
+ ret = thread.Suspend();
+ break;
+
+ default:
+ return Status(
+ "NativeProcessFreeBSD::%s (): unexpected state %s specified "
+ "for pid %" PRIu64 ", tid %" PRIu64,
+ __FUNCTION__, StateAsCString(action->state), GetID(), thread.GetID());
+ }
+
+ if (!ret.Success())
+ return ret;
+ if (action->signal != LLDB_INVALID_SIGNAL_NUMBER)
+ signal = action->signal;
+ }
+
+ ret =
+ PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), signal);
+ if (ret.Success())
+ SetState(eStateRunning, true);
+ return ret;
+}
+
+Status NativeProcessFreeBSD::Halt() {
+ Status error;
+
+ if (kill(GetID(), SIGSTOP) != 0)
+ error.SetErrorToErrno();
+ return error;
+}
+
+Status NativeProcessFreeBSD::Detach() {
+ Status error;
+
+ // Stop monitoring the inferior.
+ m_sigchld_handle.reset();
+
+ // Tell ptrace to detach from the process.
+ if (GetID() == LLDB_INVALID_PROCESS_ID)
+ return error;
+
+ return PtraceWrapper(PT_DETACH, GetID());
+}
+
+Status NativeProcessFreeBSD::Signal(int signo) {
+ Status error;
+
+ if (kill(GetID(), signo))
+ error.SetErrorToErrno();
+
+ return error;
+}
+
+Status NativeProcessFreeBSD::Interrupt() { return Halt(); }
+
+Status NativeProcessFreeBSD::Kill() {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ LLDB_LOG(log, "pid {0}", GetID());
+
+ Status error;
+
+ switch (m_state) {
+ case StateType::eStateInvalid:
+ case StateType::eStateExited:
+ case StateType::eStateCrashed:
+ case StateType::eStateDetached:
+ case StateType::eStateUnloaded:
+ // Nothing to do - the process is already dead.
+ LLDB_LOG(log, "ignored for PID {0} due to current state: {1}", GetID(),
+ StateAsCString(m_state));
+ return error;
+
+ case StateType::eStateConnected:
+ case StateType::eStateAttaching:
+ case StateType::eStateLaunching:
+ case StateType::eStateStopped:
+ case StateType::eStateRunning:
+ case StateType::eStateStepping:
+ case StateType::eStateSuspended:
+ // We can try to kill a process in these states.
+ break;
+ }
+
+ return PtraceWrapper(PT_KILL, m_pid);
+}
+
+Status NativeProcessFreeBSD::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) {
+
+ if (m_supports_mem_region == LazyBool::eLazyBoolNo) {
+ // We're done.
+ return Status("unsupported");
+ }
+
+ Status error = PopulateMemoryRegionCache();
+ if (error.Fail()) {
+ return error;
+ }
+
+ lldb::addr_t prev_base_address = 0;
+ // FIXME start by finding the last region that is <= target address using
+ // binary search. Data is sorted.
+ // There can be a ton of regions on pthreads apps with lots of threads.
+ for (auto it = m_mem_region_cache.begin(); it != m_mem_region_cache.end();
+ ++it) {
+ MemoryRegionInfo &proc_entry_info = it->first;
+ // Sanity check assumption that memory map entries are ascending.
+ assert((proc_entry_info.GetRange().GetRangeBase() >= prev_base_address) &&
+ "descending memory map entries detected, unexpected");
+ prev_base_address = proc_entry_info.GetRange().GetRangeBase();
+ UNUSED_IF_ASSERT_DISABLED(prev_base_address);
+ // If the target address comes before this entry, indicate distance to next
+ // region.
+ if (load_addr < proc_entry_info.GetRange().GetRangeBase()) {
+ range_info.GetRange().SetRangeBase(load_addr);
+ range_info.GetRange().SetByteSize(
+ proc_entry_info.GetRange().GetRangeBase() - load_addr);
+ 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;
+ } else if (proc_entry_info.GetRange().Contains(load_addr)) {
+ // The target address is within the memory region we're processing here.
+ range_info = proc_entry_info;
+ return error;
+ }
+ // The target memory address comes somewhere after the region we just
+ // parsed.
+ }
+ // If we made it here, we didn't find an entry that contained the given
+ // address. Return the 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);
+ 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;
+}
+
+Status NativeProcessFreeBSD::PopulateMemoryRegionCache() {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ // If our cache is empty, pull the latest. There should always be at least
+ // one memory region if memory region handling is supported.
+ if (!m_mem_region_cache.empty()) {
+ LLDB_LOG(log, "reusing {0} cached memory region entries",
+ m_mem_region_cache.size());
+ return Status();
+ }
+
+ int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, static_cast<int>(m_pid)};
+ int ret;
+ size_t len;
+
+ ret = ::sysctl(mib, 4, nullptr, &len, nullptr, 0);
+ if (ret != 0) {
+ m_supports_mem_region = LazyBool::eLazyBoolNo;
+ return Status("sysctl() for KERN_PROC_VMMAP failed");
+ }
+
+ std::unique_ptr<WritableMemoryBuffer> buf =
+ llvm::WritableMemoryBuffer::getNewMemBuffer(len);
+ ret = ::sysctl(mib, 4, buf->getBufferStart(), &len, nullptr, 0);
+ if (ret != 0) {
+ m_supports_mem_region = LazyBool::eLazyBoolNo;
+ return Status("sysctl() for KERN_PROC_VMMAP failed");
+ }
+
+ char *bp = buf->getBufferStart();
+ char *end = bp + len;
+ while (bp < end) {
+ auto *kv = reinterpret_cast<struct kinfo_vmentry *>(bp);
+ if (kv->kve_structsize == 0)
+ break;
+ bp += kv->kve_structsize;
+
+ MemoryRegionInfo info;
+ info.Clear();
+ info.GetRange().SetRangeBase(kv->kve_start);
+ info.GetRange().SetRangeEnd(kv->kve_end);
+ info.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
+
+ if (kv->kve_protection & VM_PROT_READ)
+ info.SetReadable(MemoryRegionInfo::OptionalBool::eYes);
+ else
+ info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
+
+ if (kv->kve_protection & VM_PROT_WRITE)
+ info.SetWritable(MemoryRegionInfo::OptionalBool::eYes);
+ else
+ info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
+
+ if (kv->kve_protection & VM_PROT_EXECUTE)
+ info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes);
+ else
+ info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
+
+ if (kv->kve_path[0])
+ info.SetName(kv->kve_path);
+
+ m_mem_region_cache.emplace_back(info,
+ FileSpec(info.GetName().GetCString()));
+ }
+
+ if (m_mem_region_cache.empty()) {
+ // No entries after attempting to read them. This shouldn't happen. Assume
+ // we don't support map entries.
+ LLDB_LOG(log, "failed to find any vmmap entries, assuming no support "
+ "for memory region metadata retrieval");
+ m_supports_mem_region = LazyBool::eLazyBoolNo;
+ return Status("not supported");
+ }
+ LLDB_LOG(log, "read {0} memory region entries from process {1}",
+ m_mem_region_cache.size(), GetID());
+ // We support memory retrieval, remember that.
+ m_supports_mem_region = LazyBool::eLazyBoolYes;
+
+ return Status();
+}
+
+size_t NativeProcessFreeBSD::UpdateThreads() { return m_threads.size(); }
+
+Status NativeProcessFreeBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size,
+ bool hardware) {
+ if (hardware)
+ return SetHardwareBreakpoint(addr, size);
+ return SetSoftwareBreakpoint(addr, size);
+}
+
+Status NativeProcessFreeBSD::GetLoadedModuleFileSpec(const char *module_path,
+ FileSpec &file_spec) {
+ Status error = PopulateMemoryRegionCache();
+ if (error.Fail())
+ return error;
+
+ FileSpec module_file_spec(module_path);
+ FileSystem::Instance().Resolve(module_file_spec);
+
+ file_spec.Clear();
+ for (const auto &it : m_mem_region_cache) {
+ if (it.second.GetFilename() == module_file_spec.GetFilename()) {
+ file_spec = it.second;
+ return Status();
+ }
+ }
+ return Status("Module file (%s) not found in process' memory map!",
+ module_file_spec.GetFilename().AsCString());
+}
+
+Status
+NativeProcessFreeBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
+ lldb::addr_t &load_addr) {
+ load_addr = LLDB_INVALID_ADDRESS;
+ Status error = PopulateMemoryRegionCache();
+ if (error.Fail())
+ return error;
+
+ FileSpec file(file_name);
+ for (const auto &it : m_mem_region_cache) {
+ if (it.second == file) {
+ load_addr = it.first.GetRange().GetRangeBase();
+ return Status();
+ }
+ }
+ return Status("No load address found for file %s.", file_name.str().c_str());
+}
+
+void NativeProcessFreeBSD::SigchldHandler() {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ // Process all pending waitpid notifications.
+ int status;
+ ::pid_t wait_pid =
+ llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status, WNOHANG);
+
+ if (wait_pid == 0)
+ return; // We are done.
+
+ if (wait_pid == -1) {
+ Status error(errno, eErrorTypePOSIX);
+ LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error);
+ }
+
+ WaitStatus wait_status = WaitStatus::Decode(status);
+ bool exited = wait_status.type == WaitStatus::Exit ||
+ (wait_status.type == WaitStatus::Signal &&
+ wait_pid == static_cast<::pid_t>(GetID()));
+
+ LLDB_LOG(log,
+ "waitpid ({0}, &status, _) => pid = {1}, status = {2}, exited = {3}",
+ GetID(), wait_pid, status, exited);
+
+ if (exited)
+ MonitorExited(wait_pid, wait_status);
+ else {
+ assert(wait_status.type == WaitStatus::Stop);
+ MonitorCallback(wait_pid, wait_status.status);
+ }
+}
+
+bool NativeProcessFreeBSD::HasThreadNoLock(lldb::tid_t thread_id) {
+ for (const auto &thread : m_threads) {
+ assert(thread && "thread list should not contain NULL threads");
+ if (thread->GetID() == thread_id) {
+ // We have this thread.
+ return true;
+ }
+ }
+
+ // We don't have this thread.
+ return false;
+}
+
+NativeThreadFreeBSD &NativeProcessFreeBSD::AddThread(lldb::tid_t thread_id) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id);
+
+ assert(thread_id > 0);
+ assert(!HasThreadNoLock(thread_id) &&
+ "attempted to add a thread by id that already exists");
+
+ // If this is the first thread, save it as the current thread
+ if (m_threads.empty())
+ SetCurrentThreadID(thread_id);
+
+ m_threads.push_back(std::make_unique<NativeThreadFreeBSD>(*this, thread_id));
+ return static_cast<NativeThreadFreeBSD &>(*m_threads.back());
+}
+
+void NativeProcessFreeBSD::RemoveThread(lldb::tid_t thread_id) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ LLDB_LOG(log, "pid {0} removing thread with tid {1}", GetID(), thread_id);
+
+ assert(thread_id > 0);
+ assert(HasThreadNoLock(thread_id) &&
+ "attempted to remove a thread that does not exist");
+
+ for (auto it = m_threads.begin(); it != m_threads.end(); ++it) {
+ if ((*it)->GetID() == thread_id) {
+ m_threads.erase(it);
+ break;
+ }
+ }
+}
+
+Status NativeProcessFreeBSD::Attach() {
+ // Attach to the requested process.
+ // An attach will cause the thread to stop with a SIGSTOP.
+ Status status = PtraceWrapper(PT_ATTACH, m_pid);
+ if (status.Fail())
+ return status;
+
+ int wstatus;
+ // Need to use WALLSIG otherwise we receive an error with errno=ECHLD At this
+ // point we should have a thread stopped if waitpid succeeds.
+ if ((wstatus = llvm::sys::RetryAfterSignal(-1, waitpid, m_pid, nullptr, 0)) <
+ 0)
+ return Status(errno, eErrorTypePOSIX);
+
+ // Initialize threads and tracing status
+ // NB: this needs to be called before we set thread state
+ status = SetupTrace();
+ if (status.Fail())
+ return status;
+
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
+
+ // Let our process instance know the thread has stopped.
+ SetCurrentThreadID(m_threads.front()->GetID());
+ SetState(StateType::eStateStopped, false);
+ return Status();
+}
+
+Status NativeProcessFreeBSD::ReadMemory(lldb::addr_t addr, void *buf,
+ size_t size, size_t &bytes_read) {
+ unsigned char *dst = static_cast<unsigned char *>(buf);
+ struct ptrace_io_desc io;
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
+ LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
+
+ bytes_read = 0;
+ io.piod_op = PIOD_READ_D;
+ io.piod_len = size;
+
+ do {
+ io.piod_offs = (void *)(addr + bytes_read);
+ io.piod_addr = dst + bytes_read;
+
+ Status error = NativeProcessFreeBSD::PtraceWrapper(PT_IO, GetID(), &io);
+ if (error.Fail() || io.piod_len == 0)
+ return error;
+
+ bytes_read += io.piod_len;
+ io.piod_len = size - bytes_read;
+ } while (bytes_read < size);
+
+ return Status();
+}
+
+Status NativeProcessFreeBSD::WriteMemory(lldb::addr_t addr, const void *buf,
+ size_t size, size_t &bytes_written) {
+ const unsigned char *src = static_cast<const unsigned char *>(buf);
+ Status error;
+ struct ptrace_io_desc io;
+
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
+ LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
+
+ bytes_written = 0;
+ io.piod_op = PIOD_WRITE_D;
+ io.piod_len = size;
+
+ do {
+ io.piod_addr =
+ const_cast<void *>(static_cast<const void *>(src + bytes_written));
+ io.piod_offs = (void *)(addr + bytes_written);
+
+ Status error = NativeProcessFreeBSD::PtraceWrapper(PT_IO, GetID(), &io);
+ if (error.Fail() || io.piod_len == 0)
+ return error;
+
+ bytes_written += io.piod_len;
+ io.piod_len = size - bytes_written;
+ } while (bytes_written < size);
+
+ return error;
+}
+
+llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+NativeProcessFreeBSD::GetAuxvData() const {
+ int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_AUXV, static_cast<int>(GetID())};
+ size_t auxv_size = AT_COUNT * sizeof(Elf_Auxinfo);
+ std::unique_ptr<WritableMemoryBuffer> buf =
+ llvm::WritableMemoryBuffer::getNewMemBuffer(auxv_size);
+
+ if (::sysctl(mib, 4, buf->getBufferStart(), &auxv_size, nullptr, 0) != 0)
+ return std::error_code(errno, std::generic_category());
+
+ return buf;
+}
+
+Status NativeProcessFreeBSD::SetupTrace() {
+ // Enable event reporting
+ int events;
+ Status status =
+ PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events));
+ if (status.Fail())
+ return status;
+ events |= PTRACE_LWP;
+ status = PtraceWrapper(PT_SET_EVENT_MASK, GetID(), &events, sizeof(events));
+ if (status.Fail())
+ return status;
+
+ return ReinitializeThreads();
+}
+
+Status NativeProcessFreeBSD::ReinitializeThreads() {
+ // Clear old threads
+ m_threads.clear();
+
+ int num_lwps;
+ Status error = PtraceWrapper(PT_GETNUMLWPS, GetID(), nullptr, 0, &num_lwps);
+ if (error.Fail())
+ return error;
+
+ std::vector<lwpid_t> lwp_ids;
+ lwp_ids.resize(num_lwps);
+ error = PtraceWrapper(PT_GETLWPLIST, GetID(), lwp_ids.data(),
+ lwp_ids.size() * sizeof(lwpid_t), &num_lwps);
+ if (error.Fail())
+ return error;
+
+ // Reinitialize from scratch threads and register them in process
+ for (lwpid_t lwp : lwp_ids)
+ AddThread(lwp);
+
+ return error;
+}
+
+bool NativeProcessFreeBSD::SupportHardwareSingleStepping() const {
+ return !m_arch.IsMIPS();
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
new file mode 100644
index 000000000000..ceffc370ca33
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
@@ -0,0 +1,128 @@
+//===-- NativeProcessFreeBSD.h -------------------------------- -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_NativeProcessFreeBSD_H_
+#define liblldb_NativeProcessFreeBSD_H_
+
+#include "Plugins/Process/POSIX/NativeProcessELF.h"
+#include "Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h"
+
+#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/FileSpec.h"
+
+#include "NativeThreadFreeBSD.h"
+
+namespace lldb_private {
+namespace process_freebsd {
+/// \class NativeProcessFreeBSD
+/// Manages communication with the inferior (debugee) process.
+///
+/// Upon construction, this class prepares and launches an inferior process
+/// for debugging.
+///
+/// Changes in the inferior process state are broadcasted.
+class NativeProcessFreeBSD : public NativeProcessELF,
+ private NativeProcessSoftwareSingleStep {
+public:
+ class Factory : public NativeProcessProtocol::Factory {
+ public:
+ llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
+ Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
+ MainLoop &mainloop) const override;
+
+ llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
+ Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
+ MainLoop &mainloop) const override;
+ };
+
+ // NativeProcessProtocol Interface
+ Status Resume(const ResumeActionList &resume_actions) override;
+
+ Status Halt() override;
+
+ Status Detach() override;
+
+ Status Signal(int signo) override;
+
+ Status Interrupt() override;
+
+ Status Kill() override;
+
+ Status GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) override;
+
+ Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
+ size_t &bytes_read) override;
+
+ Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
+ size_t &bytes_written) override;
+
+ size_t UpdateThreads() override;
+
+ const ArchSpec &GetArchitecture() const override { return m_arch; }
+
+ Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
+ bool hardware) override;
+
+ // The two following methods are probably not necessary and probably
+ // will never be called. Nevertheless, we implement them right now
+ // to reduce the differences between different platforms and reduce
+ // the risk of the lack of implementation actually breaking something,
+ // at least for the time being.
+ Status GetLoadedModuleFileSpec(const char *module_path,
+ FileSpec &file_spec) override;
+ Status GetFileLoadAddress(const llvm::StringRef &file_name,
+ lldb::addr_t &load_addr) override;
+
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+ GetAuxvData() const override;
+
+ // Interface used by NativeRegisterContext-derived classes.
+ static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
+ int data = 0, int *result = nullptr);
+
+ bool SupportHardwareSingleStepping() const;
+
+protected:
+ llvm::Expected<llvm::ArrayRef<uint8_t>>
+ GetSoftwareBreakpointTrapOpcode(size_t size_hint) override;
+
+private:
+ MainLoop::SignalHandleUP m_sigchld_handle;
+ ArchSpec m_arch;
+ LazyBool m_supports_mem_region = eLazyBoolCalculate;
+ std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
+
+ // Private Instance Methods
+ NativeProcessFreeBSD(::pid_t pid, int terminal_fd, NativeDelegate &delegate,
+ const ArchSpec &arch, MainLoop &mainloop);
+
+ bool HasThreadNoLock(lldb::tid_t thread_id);
+
+ NativeThreadFreeBSD &AddThread(lldb::tid_t thread_id);
+ void RemoveThread(lldb::tid_t thread_id);
+
+ void MonitorCallback(lldb::pid_t pid, int signal);
+ void MonitorExited(lldb::pid_t pid, WaitStatus status);
+ void MonitorSIGSTOP(lldb::pid_t pid);
+ void MonitorSIGTRAP(lldb::pid_t pid);
+ void MonitorSignal(lldb::pid_t pid, int signal);
+
+ Status PopulateMemoryRegionCache();
+ void SigchldHandler();
+
+ Status Attach();
+ Status SetupTrace();
+ Status ReinitializeThreads();
+};
+
+} // namespace process_freebsd
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_NativeProcessFreeBSD_H_
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.cpp
new file mode 100644
index 000000000000..3d744f773a26
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.cpp
@@ -0,0 +1,29 @@
+//===-- NativeRegisterContextFreeBSD.cpp ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeRegisterContextFreeBSD.h"
+
+#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"
+
+#include "lldb/Host/common/NativeProcessProtocol.h"
+
+using namespace lldb_private;
+using namespace lldb_private::process_freebsd;
+
+// clang-format off
+#include <sys/types.h>
+#include <sys/ptrace.h>
+// clang-format on
+
+NativeProcessFreeBSD &NativeRegisterContextFreeBSD::GetProcess() {
+ return static_cast<NativeProcessFreeBSD &>(m_thread.GetProcess());
+}
+
+::pid_t NativeRegisterContextFreeBSD::GetProcessPid() {
+ return GetProcess().GetID();
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h
new file mode 100644
index 000000000000..0000484beac9
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h
@@ -0,0 +1,43 @@
+//===-- NativeRegisterContextFreeBSD.h --------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_NativeRegisterContextFreeBSD_h
+#define lldb_NativeRegisterContextFreeBSD_h
+
+#include "lldb/Host/common/NativeThreadProtocol.h"
+
+#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
+
+namespace lldb_private {
+namespace process_freebsd {
+
+class NativeProcessFreeBSD;
+
+class NativeRegisterContextFreeBSD
+ : public virtual NativeRegisterContextRegisterInfo {
+public:
+ // This function is implemented in the NativeRegisterContextFreeBSD_*
+ // subclasses to create a new instance of the host specific
+ // NativeRegisterContextFreeBSD. The implementations can't collide as only one
+ // NativeRegisterContextFreeBSD_* variant should be compiled into the final
+ // executable.
+ static NativeRegisterContextFreeBSD *
+ CreateHostNativeRegisterContextFreeBSD(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread);
+ virtual llvm::Error
+ CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) = 0;
+
+protected:
+ virtual NativeProcessFreeBSD &GetProcess();
+ virtual ::pid_t GetProcessPid();
+};
+
+} // namespace process_freebsd
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextFreeBSD_h
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp
new file mode 100644
index 000000000000..c4ee3773eaeb
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp
@@ -0,0 +1,202 @@
+//===-- NativeRegisterContextFreeBSD_arm.cpp ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__arm__)
+
+#include "NativeRegisterContextFreeBSD_arm.h"
+
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+
+#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
+
+// clang-format off
+#include <sys/param.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+// clang-format on
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_freebsd;
+
+NativeRegisterContextFreeBSD *
+NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return new NativeRegisterContextFreeBSD_arm(target_arch, native_thread);
+}
+
+NativeRegisterContextFreeBSD_arm::NativeRegisterContextFreeBSD_arm(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextRegisterInfo(
+ native_thread, new RegisterInfoPOSIX_arm(target_arch)) {}
+
+RegisterInfoPOSIX_arm &
+NativeRegisterContextFreeBSD_arm::GetRegisterInfo() const {
+ return static_cast<RegisterInfoPOSIX_arm &>(*m_register_info_interface_up);
+}
+
+uint32_t NativeRegisterContextFreeBSD_arm::GetRegisterSetCount() const {
+ return GetRegisterInfo().GetRegisterSetCount();
+}
+
+const RegisterSet *
+NativeRegisterContextFreeBSD_arm::GetRegisterSet(uint32_t set_index) const {
+ return GetRegisterInfo().GetRegisterSet(set_index);
+}
+
+uint32_t NativeRegisterContextFreeBSD_arm::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
+ count += GetRegisterSet(set_index)->num_registers;
+ return count;
+}
+
+Status NativeRegisterContextFreeBSD_arm::ReadRegisterSet(uint32_t set) {
+ switch (set) {
+ case RegisterInfoPOSIX_arm::GPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(),
+ m_reg_data.data());
+ case RegisterInfoPOSIX_arm::FPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(
+ PT_GETVFPREGS, m_thread.GetID(),
+ m_reg_data.data() + sizeof(RegisterInfoPOSIX_arm::GPR));
+ }
+ llvm_unreachable("NativeRegisterContextFreeBSD_arm::ReadRegisterSet");
+}
+
+Status NativeRegisterContextFreeBSD_arm::WriteRegisterSet(uint32_t set) {
+ switch (set) {
+ case RegisterInfoPOSIX_arm::GPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(),
+ m_reg_data.data());
+ case RegisterInfoPOSIX_arm::FPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(
+ PT_SETVFPREGS, m_thread.GetID(),
+ m_reg_data.data() + sizeof(RegisterInfoPOSIX_arm::GPR));
+ }
+ llvm_unreachable("NativeRegisterContextFreeBSD_arm::WriteRegisterSet");
+}
+
+Status
+NativeRegisterContextFreeBSD_arm::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ Status error;
+
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+ if (reg == LLDB_INVALID_REGNUM)
+ return Status("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ uint32_t set = GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg);
+ error = ReadRegisterSet(set);
+ if (error.Fail())
+ return error;
+
+ assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+ reg_value.SetBytes(m_reg_data.data() + reg_info->byte_offset,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ return error;
+}
+
+Status NativeRegisterContextFreeBSD_arm::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ Status error;
+
+ if (!reg_info)
+ return Status("reg_info NULL");
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+ if (reg == LLDB_INVALID_REGNUM)
+ return Status("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ uint32_t set = GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg);
+ error = ReadRegisterSet(set);
+ if (error.Fail())
+ return error;
+
+ assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+ ::memcpy(m_reg_data.data() + reg_info->byte_offset, reg_value.GetBytes(),
+ reg_info->byte_size);
+
+ return WriteRegisterSet(set);
+}
+
+Status NativeRegisterContextFreeBSD_arm::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ error = ReadRegisterSet(RegisterInfoPOSIX_arm::GPRegSet);
+ if (error.Fail())
+ return error;
+
+ error = ReadRegisterSet(RegisterInfoPOSIX_arm::FPRegSet);
+ if (error.Fail())
+ return error;
+
+ data_sp.reset(new DataBufferHeap(m_reg_data.size(), 0));
+ uint8_t *dst = data_sp->GetBytes();
+ ::memcpy(dst, m_reg_data.data(), m_reg_data.size());
+
+ return error;
+}
+
+Status NativeRegisterContextFreeBSD_arm::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextFreeBSD_arm::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
+
+ if (data_sp->GetByteSize() != m_reg_data.size()) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextFreeBSD_arm::%s data_sp contained mismatched "
+ "data size, expected %" PRIu64 ", actual %" PRIu64,
+ __FUNCTION__, m_reg_data.size(), data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_arm::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ ::memcpy(m_reg_data.data(), src, m_reg_data.size());
+
+ error = WriteRegisterSet(RegisterInfoPOSIX_arm::GPRegSet);
+ if (error.Fail())
+ return error;
+
+ return WriteRegisterSet(RegisterInfoPOSIX_arm::FPRegSet);
+}
+
+llvm::Error NativeRegisterContextFreeBSD_arm::CopyHardwareWatchpointsFrom(
+ NativeRegisterContextFreeBSD &source) {
+ return llvm::Error::success();
+}
+
+#endif // defined (__arm__)
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.h
new file mode 100644
index 000000000000..4be75b958fc1
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.h
@@ -0,0 +1,68 @@
+//===-- NativeRegisterContextFreeBSD_arm.h ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__arm__)
+
+#ifndef lldb_NativeRegisterContextFreeBSD_arm_h
+#define lldb_NativeRegisterContextFreeBSD_arm_h
+
+// clang-format off
+#include <sys/types.h>
+#include <machine/reg.h>
+#include <machine/vfp.h>
+// clang-format on
+
+#include "Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
+
+#include <array>
+
+namespace lldb_private {
+namespace process_freebsd {
+
+class NativeProcessFreeBSD;
+
+class NativeRegisterContextFreeBSD_arm : public NativeRegisterContextFreeBSD {
+public:
+ NativeRegisterContextFreeBSD_arm(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread);
+
+ uint32_t GetRegisterSetCount() const override;
+
+ uint32_t GetUserRegisterCount() const override;
+
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
+
+ Status ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
+
+ Status WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
+
+ Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ llvm::Error
+ CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) override;
+
+private:
+ std::array<uint8_t, sizeof(reg) + sizeof(vfp_state)> m_reg_data;
+
+ Status ReadRegisterSet(uint32_t set);
+ Status WriteRegisterSet(uint32_t set);
+
+ RegisterInfoPOSIX_arm &GetRegisterInfo() const;
+};
+
+} // namespace process_freebsd
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextFreeBSD_arm_h
+
+#endif // defined (__arm__)
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
new file mode 100644
index 000000000000..e98e0a8a0caa
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
@@ -0,0 +1,288 @@
+//===-- NativeRegisterContextFreeBSD_arm64.cpp ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__aarch64__)
+
+#include "NativeRegisterContextFreeBSD_arm64.h"
+
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+
+#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+
+// clang-format off
+#include <sys/param.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+// clang-format on
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_freebsd;
+
+NativeRegisterContextFreeBSD *
+NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return new NativeRegisterContextFreeBSD_arm64(target_arch, native_thread);
+}
+
+NativeRegisterContextFreeBSD_arm64::NativeRegisterContextFreeBSD_arm64(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextRegisterInfo(
+ native_thread, new RegisterInfoPOSIX_arm64(target_arch))
+#ifdef LLDB_HAS_FREEBSD_WATCHPOINT
+ ,
+ m_read_dbreg(false)
+#endif
+{
+ GetRegisterInfo().ConfigureVectorRegisterInfos(
+ RegisterInfoPOSIX_arm64::eVectorQuadwordAArch64);
+ ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
+ ::memset(&m_hbp_regs, 0, sizeof(m_hbp_regs));
+}
+
+RegisterInfoPOSIX_arm64 &
+NativeRegisterContextFreeBSD_arm64::GetRegisterInfo() const {
+ return static_cast<RegisterInfoPOSIX_arm64 &>(*m_register_info_interface_up);
+}
+
+uint32_t NativeRegisterContextFreeBSD_arm64::GetRegisterSetCount() const {
+ return GetRegisterInfo().GetRegisterSetCount();
+}
+
+const RegisterSet *
+NativeRegisterContextFreeBSD_arm64::GetRegisterSet(uint32_t set_index) const {
+ return GetRegisterInfo().GetRegisterSet(set_index);
+}
+
+uint32_t NativeRegisterContextFreeBSD_arm64::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
+ count += GetRegisterSet(set_index)->num_registers;
+ return count;
+}
+
+Status NativeRegisterContextFreeBSD_arm64::ReadRegisterSet(uint32_t set) {
+ switch (set) {
+ case RegisterInfoPOSIX_arm64::GPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(),
+ m_reg_data.data());
+ case RegisterInfoPOSIX_arm64::FPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(
+ PT_GETFPREGS, m_thread.GetID(),
+ m_reg_data.data() + sizeof(RegisterInfoPOSIX_arm64::GPR));
+ case RegisterInfoPOSIX_arm64::SVERegSet:
+ return Status("not supported");
+ }
+ llvm_unreachable("NativeRegisterContextFreeBSD_arm64::ReadRegisterSet");
+}
+
+Status NativeRegisterContextFreeBSD_arm64::WriteRegisterSet(uint32_t set) {
+ switch (set) {
+ case RegisterInfoPOSIX_arm64::GPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(),
+ m_reg_data.data());
+ case RegisterInfoPOSIX_arm64::FPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(
+ PT_SETFPREGS, m_thread.GetID(),
+ m_reg_data.data() + sizeof(RegisterInfoPOSIX_arm64::GPR));
+ case RegisterInfoPOSIX_arm64::SVERegSet:
+ return Status("not supported");
+ }
+ llvm_unreachable("NativeRegisterContextFreeBSD_arm64::WriteRegisterSet");
+}
+
+Status
+NativeRegisterContextFreeBSD_arm64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ Status error;
+
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+ if (reg == LLDB_INVALID_REGNUM)
+ return Status("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ uint32_t set = GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg);
+ error = ReadRegisterSet(set);
+ if (error.Fail())
+ return error;
+
+ assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+ reg_value.SetBytes(m_reg_data.data() + reg_info->byte_offset,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ return error;
+}
+
+Status NativeRegisterContextFreeBSD_arm64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ Status error;
+
+ if (!reg_info)
+ return Status("reg_info NULL");
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+ if (reg == LLDB_INVALID_REGNUM)
+ return Status("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ uint32_t set = GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg);
+ error = ReadRegisterSet(set);
+ if (error.Fail())
+ return error;
+
+ assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+ ::memcpy(m_reg_data.data() + reg_info->byte_offset, reg_value.GetBytes(),
+ reg_info->byte_size);
+
+ return WriteRegisterSet(set);
+}
+
+Status NativeRegisterContextFreeBSD_arm64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ error = ReadRegisterSet(RegisterInfoPOSIX_arm64::GPRegSet);
+ if (error.Fail())
+ return error;
+
+ error = ReadRegisterSet(RegisterInfoPOSIX_arm64::FPRegSet);
+ if (error.Fail())
+ return error;
+
+ data_sp.reset(new DataBufferHeap(m_reg_data.size(), 0));
+ uint8_t *dst = data_sp->GetBytes();
+ ::memcpy(dst, m_reg_data.data(), m_reg_data.size());
+
+ return error;
+}
+
+Status NativeRegisterContextFreeBSD_arm64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextFreeBSD_arm64::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
+
+ if (data_sp->GetByteSize() != m_reg_data.size()) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextFreeBSD_arm64::%s data_sp contained mismatched "
+ "data size, expected %" PRIu64 ", actual %" PRIu64,
+ __FUNCTION__, m_reg_data.size(), data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_arm64::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ ::memcpy(m_reg_data.data(), src, m_reg_data.size());
+
+ error = WriteRegisterSet(RegisterInfoPOSIX_arm64::GPRegSet);
+ if (error.Fail())
+ return error;
+
+ return WriteRegisterSet(RegisterInfoPOSIX_arm64::FPRegSet);
+}
+
+llvm::Error NativeRegisterContextFreeBSD_arm64::CopyHardwareWatchpointsFrom(
+ NativeRegisterContextFreeBSD &source) {
+#ifdef LLDB_HAS_FREEBSD_WATCHPOINT
+ auto &r_source = static_cast<NativeRegisterContextFreeBSD_arm64 &>(source);
+ llvm::Error error = r_source.ReadHardwareDebugInfo();
+ if (error)
+ return error;
+
+ m_dbreg = r_source.m_dbreg;
+ m_hbp_regs = r_source.m_hbp_regs;
+ m_hwp_regs = r_source.m_hwp_regs;
+ m_max_hbp_supported = r_source.m_max_hbp_supported;
+ m_max_hwp_supported = r_source.m_max_hwp_supported;
+ m_read_dbreg = true;
+
+ // on FreeBSD this writes both breakpoints and watchpoints
+ return WriteHardwareDebugRegs(eDREGTypeWATCH);
+#else
+ return llvm::Error::success();
+#endif
+}
+
+llvm::Error NativeRegisterContextFreeBSD_arm64::ReadHardwareDebugInfo() {
+#ifdef LLDB_HAS_FREEBSD_WATCHPOINT
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_REGISTERS));
+
+ // we're fully stateful, so no need to reread control registers ever
+ if (m_read_dbreg)
+ return llvm::Error::success();
+
+ Status res = NativeProcessFreeBSD::PtraceWrapper(PT_GETDBREGS,
+ m_thread.GetID(), &m_dbreg);
+ if (res.Fail())
+ return res.ToError();
+
+ LLDB_LOG(log, "m_dbreg read: debug_ver={0}, nbkpts={1}, nwtpts={2}",
+ m_dbreg.db_debug_ver, m_dbreg.db_nbkpts, m_dbreg.db_nwtpts);
+ m_max_hbp_supported = m_dbreg.db_nbkpts;
+ m_max_hwp_supported = m_dbreg.db_nwtpts;
+ assert(m_max_hbp_supported <= m_hbp_regs.size());
+ assert(m_max_hwp_supported <= m_hwp_regs.size());
+
+ m_read_dbreg = true;
+ return llvm::Error::success();
+#else
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Hardware breakpoints/watchpoints require FreeBSD 14.0");
+#endif
+}
+
+llvm::Error
+NativeRegisterContextFreeBSD_arm64::WriteHardwareDebugRegs(DREGType) {
+#ifdef LLDB_HAS_FREEBSD_WATCHPOINT
+ assert(m_read_dbreg && "dbregs must be read before writing them back");
+
+ // copy data from m_*_regs to m_dbreg before writing it back
+ for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
+ m_dbreg.db_breakregs[i].dbr_addr = m_hbp_regs[i].address;
+ m_dbreg.db_breakregs[i].dbr_ctrl = m_hbp_regs[i].control;
+ }
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ m_dbreg.db_watchregs[i].dbw_addr = m_hwp_regs[i].address;
+ m_dbreg.db_watchregs[i].dbw_ctrl = m_hwp_regs[i].control;
+ }
+
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETDBREGS, m_thread.GetID(),
+ &m_dbreg)
+ .ToError();
+#else
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Hardware breakpoints/watchpoints require FreeBSD 14.0");
+#endif
+}
+
+#endif // defined (__aarch64__)
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h
new file mode 100644
index 000000000000..a230f8fed48a
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h
@@ -0,0 +1,86 @@
+//===-- NativeRegisterContextFreeBSD_arm64.h --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__aarch64__)
+
+#ifndef lldb_NativeRegisterContextFreeBSD_arm64_h
+#define lldb_NativeRegisterContextFreeBSD_arm64_h
+
+// clang-format off
+#include <sys/types.h>
+#include <sys/param.h>
+#include <machine/reg.h>
+// clang-format on
+
+#include "Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h"
+#include "Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+
+#include <array>
+
+#if __FreeBSD_version >= 1300139
+# define LLDB_HAS_FREEBSD_WATCHPOINT 1
+#endif
+
+namespace lldb_private {
+namespace process_freebsd {
+
+class NativeProcessFreeBSD;
+
+class NativeRegisterContextFreeBSD_arm64
+ : public NativeRegisterContextFreeBSD,
+ public NativeRegisterContextDBReg_arm64 {
+public:
+ NativeRegisterContextFreeBSD_arm64(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread);
+
+ uint32_t GetRegisterSetCount() const override;
+
+ uint32_t GetUserRegisterCount() const override;
+
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
+
+ Status ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
+
+ Status WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
+
+ Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ llvm::Error
+ CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) override;
+
+private:
+ // Due to alignment, FreeBSD reg/fpreg are a few bytes larger than
+ // LLDB's GPR/FPU structs. However, all fields have matching offsets
+ // and sizes, so we do not have to worry about these (and we have
+ // a unittest to assert that).
+ std::array<uint8_t, sizeof(reg) + sizeof(fpreg)> m_reg_data;
+#ifdef LLDB_HAS_FREEBSD_WATCHPOINT
+ dbreg m_dbreg;
+ bool m_read_dbreg;
+#endif
+
+ Status ReadRegisterSet(uint32_t set);
+ Status WriteRegisterSet(uint32_t set);
+
+ llvm::Error ReadHardwareDebugInfo() override;
+ llvm::Error WriteHardwareDebugRegs(DREGType hwbType) override;
+
+ RegisterInfoPOSIX_arm64 &GetRegisterInfo() const;
+};
+
+} // namespace process_freebsd
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextFreeBSD_arm64_h
+
+#endif // defined (__aarch64__)
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp
new file mode 100644
index 000000000000..8e722c09314c
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp
@@ -0,0 +1,186 @@
+//===-- NativeRegisterContextFreeBSD_mips64.cpp ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__mips64__)
+
+#include "NativeRegisterContextFreeBSD_mips64.h"
+
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+
+#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"
+
+// clang-format off
+#include <sys/param.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+// clang-format on
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_freebsd;
+
+NativeRegisterContextFreeBSD *
+NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return new NativeRegisterContextFreeBSD_mips64(target_arch, native_thread);
+}
+
+NativeRegisterContextFreeBSD_mips64::NativeRegisterContextFreeBSD_mips64(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextRegisterInfo(
+ native_thread, new RegisterContextFreeBSD_mips64(target_arch)) {}
+
+RegisterContextFreeBSD_mips64 &
+NativeRegisterContextFreeBSD_mips64::GetRegisterInfo() const {
+ return static_cast<RegisterContextFreeBSD_mips64 &>(
+ *m_register_info_interface_up);
+}
+
+uint32_t NativeRegisterContextFreeBSD_mips64::GetRegisterSetCount() const {
+ return GetRegisterInfo().GetRegisterSetCount();
+}
+
+const RegisterSet *
+NativeRegisterContextFreeBSD_mips64::GetRegisterSet(uint32_t set_index) const {
+ return GetRegisterInfo().GetRegisterSet(set_index);
+}
+
+uint32_t NativeRegisterContextFreeBSD_mips64::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
+ count += GetRegisterSet(set_index)->num_registers;
+ return count;
+}
+
+Status NativeRegisterContextFreeBSD_mips64::ReadRegisterSet(RegSetKind set) {
+ switch (set) {
+ case GPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(),
+ m_reg_data.data());
+ }
+ llvm_unreachable("NativeRegisterContextFreeBSD_mips64::ReadRegisterSet");
+}
+
+Status NativeRegisterContextFreeBSD_mips64::WriteRegisterSet(RegSetKind set) {
+ switch (set) {
+ case GPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(),
+ m_reg_data.data());
+ }
+ llvm_unreachable("NativeRegisterContextFreeBSD_mips64::WriteRegisterSet");
+}
+
+Status
+NativeRegisterContextFreeBSD_mips64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ Status error;
+
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+ if (reg == LLDB_INVALID_REGNUM)
+ return Status("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ RegSetKind set = GPRegSet;
+ error = ReadRegisterSet(set);
+ if (error.Fail())
+ return error;
+
+ assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+ reg_value.SetBytes(m_reg_data.data() + reg_info->byte_offset,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ return error;
+}
+
+Status NativeRegisterContextFreeBSD_mips64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ Status error;
+
+ if (!reg_info)
+ return Status("reg_info NULL");
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+ if (reg == LLDB_INVALID_REGNUM)
+ return Status("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ RegSetKind set = GPRegSet;
+ error = ReadRegisterSet(set);
+ if (error.Fail())
+ return error;
+
+ assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+ ::memcpy(m_reg_data.data() + reg_info->byte_offset, reg_value.GetBytes(),
+ reg_info->byte_size);
+
+ return WriteRegisterSet(set);
+}
+
+Status NativeRegisterContextFreeBSD_mips64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ error = ReadRegisterSet(GPRegSet);
+ if (error.Fail())
+ return error;
+
+ data_sp.reset(new DataBufferHeap(m_reg_data.size(), 0));
+ uint8_t *dst = data_sp->GetBytes();
+ ::memcpy(dst, m_reg_data.data(), m_reg_data.size());
+
+ return error;
+}
+
+Status NativeRegisterContextFreeBSD_mips64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextFreeBSD_mips64::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
+
+ if (data_sp->GetByteSize() != m_reg_data.size()) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextFreeBSD_mips64::%s data_sp contained mismatched "
+ "data size, expected %" PRIu64 ", actual %" PRIu64,
+ __FUNCTION__, m_reg_data.size(), data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_mips64::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ ::memcpy(m_reg_data.data(), src, m_reg_data.size());
+
+ return WriteRegisterSet(GPRegSet);
+}
+
+llvm::Error NativeRegisterContextFreeBSD_mips64::CopyHardwareWatchpointsFrom(
+ NativeRegisterContextFreeBSD &source) {
+ return llvm::Error::success();
+}
+
+#endif // defined (__mips64__)
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h
new file mode 100644
index 000000000000..6a3eb86a9231
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h
@@ -0,0 +1,71 @@
+//===-- NativeRegisterContextFreeBSD_mips64.h -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__mips64__)
+
+#ifndef lldb_NativeRegisterContextFreeBSD_mips64_h
+#define lldb_NativeRegisterContextFreeBSD_mips64_h
+
+// clang-format off
+#include <sys/types.h>
+#include <machine/reg.h>
+// clang-format on
+
+#include "Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
+
+#include <array>
+
+namespace lldb_private {
+namespace process_freebsd {
+
+class NativeProcessFreeBSD;
+
+class NativeRegisterContextFreeBSD_mips64
+ : public NativeRegisterContextFreeBSD {
+public:
+ NativeRegisterContextFreeBSD_mips64(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread);
+
+ uint32_t GetRegisterSetCount() const override;
+
+ uint32_t GetUserRegisterCount() const override;
+
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
+
+ Status ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
+
+ Status WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
+
+ Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ llvm::Error
+ CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) override;
+
+private:
+ enum RegSetKind {
+ GPRegSet,
+ };
+ std::array<uint8_t, sizeof(reg)> m_reg_data;
+
+ Status ReadRegisterSet(RegSetKind set);
+ Status WriteRegisterSet(RegSetKind set);
+
+ RegisterContextFreeBSD_mips64 &GetRegisterInfo() const;
+};
+
+} // namespace process_freebsd
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextFreeBSD_mips64_h
+
+#endif // defined (__mips64__)
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp
new file mode 100644
index 000000000000..5b5d44a308b1
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp
@@ -0,0 +1,289 @@
+//===-- NativeRegisterContextFreeBSD_powerpc.cpp --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__powerpc__)
+
+#include "NativeRegisterContextFreeBSD_powerpc.h"
+
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+
+#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"
+// for register enum definitions
+#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
+
+// clang-format off
+#include <sys/param.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+// clang-format on
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_freebsd;
+
+static const uint32_t g_gpr_regnums[] = {
+ gpr_r0_powerpc, gpr_r1_powerpc, gpr_r2_powerpc, gpr_r3_powerpc,
+ gpr_r4_powerpc, gpr_r5_powerpc, gpr_r6_powerpc, gpr_r7_powerpc,
+ gpr_r8_powerpc, gpr_r9_powerpc, gpr_r10_powerpc, gpr_r11_powerpc,
+ gpr_r12_powerpc, gpr_r13_powerpc, gpr_r14_powerpc, gpr_r15_powerpc,
+ gpr_r16_powerpc, gpr_r17_powerpc, gpr_r18_powerpc, gpr_r19_powerpc,
+ gpr_r20_powerpc, gpr_r21_powerpc, gpr_r22_powerpc, gpr_r23_powerpc,
+ gpr_r24_powerpc, gpr_r25_powerpc, gpr_r26_powerpc, gpr_r27_powerpc,
+ gpr_r28_powerpc, gpr_r29_powerpc, gpr_r30_powerpc, gpr_r31_powerpc,
+ gpr_lr_powerpc, gpr_cr_powerpc, gpr_xer_powerpc, gpr_ctr_powerpc,
+ gpr_pc_powerpc,
+};
+
+static const uint32_t g_fpr_regnums[] = {
+ fpr_f0_powerpc, fpr_f1_powerpc, fpr_f2_powerpc, fpr_f3_powerpc,
+ fpr_f4_powerpc, fpr_f5_powerpc, fpr_f6_powerpc, fpr_f7_powerpc,
+ fpr_f8_powerpc, fpr_f9_powerpc, fpr_f10_powerpc, fpr_f11_powerpc,
+ fpr_f12_powerpc, fpr_f13_powerpc, fpr_f14_powerpc, fpr_f15_powerpc,
+ fpr_f16_powerpc, fpr_f17_powerpc, fpr_f18_powerpc, fpr_f19_powerpc,
+ fpr_f20_powerpc, fpr_f21_powerpc, fpr_f22_powerpc, fpr_f23_powerpc,
+ fpr_f24_powerpc, fpr_f25_powerpc, fpr_f26_powerpc, fpr_f27_powerpc,
+ fpr_f28_powerpc, fpr_f29_powerpc, fpr_f30_powerpc, fpr_f31_powerpc,
+ fpr_fpscr_powerpc,
+};
+
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 2 };
+
+static const RegisterSet g_reg_sets_powerpc[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_powerpc,
+ g_gpr_regnums},
+ {"Floating Point Registers", "fpr", k_num_fpr_registers_powerpc,
+ g_fpr_regnums},
+};
+
+NativeRegisterContextFreeBSD *
+NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return new NativeRegisterContextFreeBSD_powerpc(target_arch, native_thread);
+}
+
+static RegisterInfoInterface *
+CreateRegisterInfoInterface(const ArchSpec &target_arch) {
+ if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
+ return new RegisterContextFreeBSD_powerpc32(target_arch);
+ } else {
+ assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
+ "Register setting path assumes this is a 64-bit host");
+ return new RegisterContextFreeBSD_powerpc64(target_arch);
+ }
+}
+
+NativeRegisterContextFreeBSD_powerpc::NativeRegisterContextFreeBSD_powerpc(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextRegisterInfo(
+ native_thread, CreateRegisterInfoInterface(target_arch)) {}
+
+RegisterContextFreeBSD_powerpc &
+NativeRegisterContextFreeBSD_powerpc::GetRegisterInfo() const {
+ return static_cast<RegisterContextFreeBSD_powerpc &>(
+ *m_register_info_interface_up);
+}
+
+uint32_t NativeRegisterContextFreeBSD_powerpc::GetRegisterSetCount() const {
+ return k_num_register_sets;
+}
+
+const RegisterSet *
+NativeRegisterContextFreeBSD_powerpc::GetRegisterSet(uint32_t set_index) const {
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::ppc:
+ return &g_reg_sets_powerpc[set_index];
+ default:
+ llvm_unreachable("Unhandled target architecture.");
+ }
+}
+
+llvm::Optional<NativeRegisterContextFreeBSD_powerpc::RegSetKind>
+NativeRegisterContextFreeBSD_powerpc::GetSetForNativeRegNum(
+ uint32_t reg_num) const {
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::ppc:
+ if (reg_num >= k_first_gpr_powerpc && reg_num <= k_last_gpr_powerpc)
+ return GPRegSet;
+ if (reg_num >= k_first_fpr && reg_num <= k_last_fpr)
+ return FPRegSet;
+ break;
+ default:
+ llvm_unreachable("Unhandled target architecture.");
+ }
+
+ llvm_unreachable("Register does not belong to any register set");
+}
+
+uint32_t NativeRegisterContextFreeBSD_powerpc::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
+ count += GetRegisterSet(set_index)->num_registers;
+ return count;
+}
+
+Status NativeRegisterContextFreeBSD_powerpc::ReadRegisterSet(RegSetKind set) {
+ switch (set) {
+ case GPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(),
+ m_reg_data.data());
+ case FPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_GETFPREGS, m_thread.GetID(),
+ m_reg_data.data() + sizeof(reg));
+ }
+ llvm_unreachable("NativeRegisterContextFreeBSD_powerpc::ReadRegisterSet");
+}
+
+Status NativeRegisterContextFreeBSD_powerpc::WriteRegisterSet(RegSetKind set) {
+ switch (set) {
+ case GPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(),
+ m_reg_data.data());
+ case FPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETFPREGS, m_thread.GetID(),
+ m_reg_data.data() + sizeof(reg));
+ }
+ llvm_unreachable("NativeRegisterContextFreeBSD_powerpc::WriteRegisterSet");
+}
+
+Status
+NativeRegisterContextFreeBSD_powerpc::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ Status error;
+
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+ if (reg == LLDB_INVALID_REGNUM)
+ return Status("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);
+ if (!opt_set) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
+ reg_info->name);
+ return error;
+ }
+
+ RegSetKind set = opt_set.getValue();
+ error = ReadRegisterSet(set);
+ if (error.Fail())
+ return error;
+
+ assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+ reg_value.SetBytes(m_reg_data.data() + reg_info->byte_offset,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ return error;
+}
+
+Status NativeRegisterContextFreeBSD_powerpc::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ Status error;
+
+ if (!reg_info)
+ return Status("reg_info NULL");
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+ if (reg == LLDB_INVALID_REGNUM)
+ return Status("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);
+ if (!opt_set) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
+ reg_info->name);
+ return error;
+ }
+
+ RegSetKind set = opt_set.getValue();
+ error = ReadRegisterSet(set);
+ if (error.Fail())
+ return error;
+
+ assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+ ::memcpy(m_reg_data.data() + reg_info->byte_offset, reg_value.GetBytes(),
+ reg_info->byte_size);
+
+ return WriteRegisterSet(set);
+}
+
+Status NativeRegisterContextFreeBSD_powerpc::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ error = ReadRegisterSet(GPRegSet);
+ if (error.Fail())
+ return error;
+
+ error = ReadRegisterSet(FPRegSet);
+ if (error.Fail())
+ return error;
+
+ data_sp.reset(new DataBufferHeap(m_reg_data.size(), 0));
+ uint8_t *dst = data_sp->GetBytes();
+ ::memcpy(dst, m_reg_data.data(), m_reg_data.size());
+
+ return error;
+}
+
+Status NativeRegisterContextFreeBSD_powerpc::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextFreeBSD_powerpc::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
+
+ if (data_sp->GetByteSize() != m_reg_data.size()) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextFreeBSD_powerpc::%s data_sp contained mismatched "
+ "data size, expected %zu, actual %" PRIu64,
+ __FUNCTION__, m_reg_data.size(), data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_powerpc::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ ::memcpy(m_reg_data.data(), src, m_reg_data.size());
+
+ error = WriteRegisterSet(GPRegSet);
+ if (error.Fail())
+ return error;
+
+ return WriteRegisterSet(FPRegSet);
+}
+
+llvm::Error NativeRegisterContextFreeBSD_powerpc::CopyHardwareWatchpointsFrom(
+ NativeRegisterContextFreeBSD &source) {
+ return llvm::Error::success();
+}
+
+#endif // defined (__powerpc__)
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.h
new file mode 100644
index 000000000000..884c25988ce1
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.h
@@ -0,0 +1,74 @@
+//===-- NativeRegisterContextFreeBSD_powerpc.h ------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__powerpc__)
+
+#ifndef lldb_NativeRegisterContextFreeBSD_powerpc_h
+#define lldb_NativeRegisterContextFreeBSD_powerpc_h
+
+// clang-format off
+#include <sys/types.h>
+#include <machine/reg.h>
+// clang-format on
+
+#include "Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
+
+#include <array>
+
+namespace lldb_private {
+namespace process_freebsd {
+
+class NativeProcessFreeBSD;
+
+class NativeRegisterContextFreeBSD_powerpc
+ : public NativeRegisterContextFreeBSD {
+public:
+ NativeRegisterContextFreeBSD_powerpc(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread);
+
+ uint32_t GetRegisterSetCount() const override;
+
+ uint32_t GetUserRegisterCount() const override;
+
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
+
+ Status ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
+
+ Status WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
+
+ Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ llvm::Error
+ CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) override;
+
+private:
+ enum RegSetKind {
+ GPRegSet,
+ FPRegSet,
+ };
+ std::array<uint8_t, sizeof(reg) + sizeof(fpreg)> m_reg_data;
+
+ llvm::Optional<RegSetKind> GetSetForNativeRegNum(uint32_t reg_num) const;
+
+ Status ReadRegisterSet(RegSetKind set);
+ Status WriteRegisterSet(RegSetKind set);
+
+ RegisterContextFreeBSD_powerpc &GetRegisterInfo() const;
+};
+
+} // namespace process_freebsd
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextFreeBSD_powerpc_h
+
+#endif // defined (__powerpc__)
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp
new file mode 100644
index 000000000000..d5052e7d1b3a
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp
@@ -0,0 +1,656 @@
+//===-- NativeRegisterContextFreeBSD_x86_64.cpp ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__i386__) || defined(__x86_64__)
+
+#include "NativeRegisterContextFreeBSD_x86_64.h"
+
+// clang-format off
+#include <x86/fpu.h>
+#include <x86/specialreg.h>
+#include <cpuid.h>
+// clang-format on
+
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+
+#include "NativeProcessFreeBSD.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
+
+using namespace lldb_private;
+using namespace lldb_private::process_freebsd;
+
+// x86 64-bit general purpose registers.
+static const uint32_t g_gpr_regnums_x86_64[] = {
+ lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64,
+ lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rbp_x86_64, lldb_rsp_x86_64,
+ lldb_r8_x86_64, lldb_r9_x86_64, lldb_r10_x86_64, lldb_r11_x86_64,
+ lldb_r12_x86_64, lldb_r13_x86_64, lldb_r14_x86_64, lldb_r15_x86_64,
+ lldb_rip_x86_64, lldb_rflags_x86_64, lldb_cs_x86_64, lldb_fs_x86_64,
+ lldb_gs_x86_64, lldb_ss_x86_64, lldb_ds_x86_64, lldb_es_x86_64,
+ lldb_eax_x86_64, lldb_ebx_x86_64, lldb_ecx_x86_64, lldb_edx_x86_64,
+ lldb_edi_x86_64, lldb_esi_x86_64, lldb_ebp_x86_64, lldb_esp_x86_64,
+ lldb_r8d_x86_64, // Low 32 bits or r8
+ lldb_r9d_x86_64, // Low 32 bits or r9
+ lldb_r10d_x86_64, // Low 32 bits or r10
+ lldb_r11d_x86_64, // Low 32 bits or r11
+ lldb_r12d_x86_64, // Low 32 bits or r12
+ lldb_r13d_x86_64, // Low 32 bits or r13
+ lldb_r14d_x86_64, // Low 32 bits or r14
+ lldb_r15d_x86_64, // Low 32 bits or r15
+ lldb_ax_x86_64, lldb_bx_x86_64, lldb_cx_x86_64, lldb_dx_x86_64,
+ lldb_di_x86_64, lldb_si_x86_64, lldb_bp_x86_64, lldb_sp_x86_64,
+ lldb_r8w_x86_64, // Low 16 bits or r8
+ lldb_r9w_x86_64, // Low 16 bits or r9
+ lldb_r10w_x86_64, // Low 16 bits or r10
+ lldb_r11w_x86_64, // Low 16 bits or r11
+ lldb_r12w_x86_64, // Low 16 bits or r12
+ lldb_r13w_x86_64, // Low 16 bits or r13
+ lldb_r14w_x86_64, // Low 16 bits or r14
+ lldb_r15w_x86_64, // Low 16 bits or r15
+ lldb_ah_x86_64, lldb_bh_x86_64, lldb_ch_x86_64, lldb_dh_x86_64,
+ lldb_al_x86_64, lldb_bl_x86_64, lldb_cl_x86_64, lldb_dl_x86_64,
+ lldb_dil_x86_64, lldb_sil_x86_64, lldb_bpl_x86_64, lldb_spl_x86_64,
+ lldb_r8l_x86_64, // Low 8 bits or r8
+ lldb_r9l_x86_64, // Low 8 bits or r9
+ lldb_r10l_x86_64, // Low 8 bits or r10
+ lldb_r11l_x86_64, // Low 8 bits or r11
+ lldb_r12l_x86_64, // Low 8 bits or r12
+ lldb_r13l_x86_64, // Low 8 bits or r13
+ lldb_r14l_x86_64, // Low 8 bits or r14
+ lldb_r15l_x86_64, // Low 8 bits or r15
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
+ 1 ==
+ k_num_gpr_registers_x86_64,
+ "g_gpr_regnums_x86_64 has wrong number of register infos");
+
+// x86 64-bit floating point registers.
+static const uint32_t g_fpu_regnums_x86_64[] = {
+ lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64,
+ lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64,
+ lldb_fip_x86_64, lldb_foseg_x86_64, lldb_fooff_x86_64,
+ lldb_fdp_x86_64, lldb_mxcsr_x86_64, lldb_mxcsrmask_x86_64,
+ lldb_st0_x86_64, lldb_st1_x86_64, lldb_st2_x86_64,
+ lldb_st3_x86_64, lldb_st4_x86_64, lldb_st5_x86_64,
+ lldb_st6_x86_64, lldb_st7_x86_64, lldb_mm0_x86_64,
+ lldb_mm1_x86_64, lldb_mm2_x86_64, lldb_mm3_x86_64,
+ lldb_mm4_x86_64, lldb_mm5_x86_64, lldb_mm6_x86_64,
+ lldb_mm7_x86_64, lldb_xmm0_x86_64, lldb_xmm1_x86_64,
+ lldb_xmm2_x86_64, lldb_xmm3_x86_64, lldb_xmm4_x86_64,
+ lldb_xmm5_x86_64, lldb_xmm6_x86_64, lldb_xmm7_x86_64,
+ lldb_xmm8_x86_64, lldb_xmm9_x86_64, lldb_xmm10_x86_64,
+ lldb_xmm11_x86_64, lldb_xmm12_x86_64, lldb_xmm13_x86_64,
+ lldb_xmm14_x86_64, lldb_xmm15_x86_64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) -
+ 1 ==
+ k_num_fpr_registers_x86_64,
+ "g_fpu_regnums_x86_64 has wrong number of register infos");
+
+static const uint32_t g_avx_regnums_x86_64[] = {
+ lldb_ymm0_x86_64, lldb_ymm1_x86_64, lldb_ymm2_x86_64, lldb_ymm3_x86_64,
+ lldb_ymm4_x86_64, lldb_ymm5_x86_64, lldb_ymm6_x86_64, lldb_ymm7_x86_64,
+ lldb_ymm8_x86_64, lldb_ymm9_x86_64, lldb_ymm10_x86_64, lldb_ymm11_x86_64,
+ lldb_ymm12_x86_64, lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -
+ 1 ==
+ k_num_avx_registers_x86_64,
+ "g_avx_regnums_x86_64 has wrong number of register infos");
+
+static const uint32_t g_mpx_regnums_x86_64[] = {
+ // Note: we currently do not provide them but this is needed to avoid
+ // unnamed groups in SBFrame::GetRegisterContext().
+ lldb_bnd0_x86_64, lldb_bnd1_x86_64, lldb_bnd2_x86_64,
+ lldb_bnd3_x86_64, lldb_bndcfgu_x86_64, lldb_bndstatus_x86_64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_mpx_regnums_x86_64) / sizeof(g_mpx_regnums_x86_64[0])) -
+ 1 ==
+ k_num_mpx_registers_x86_64,
+ "g_mpx_regnums_x86_64 has wrong number of register infos");
+
+// x86 debug registers.
+static const uint32_t g_dbr_regnums_x86_64[] = {
+ lldb_dr0_x86_64, lldb_dr1_x86_64, lldb_dr2_x86_64, lldb_dr3_x86_64,
+ lldb_dr4_x86_64, lldb_dr5_x86_64, lldb_dr6_x86_64, lldb_dr7_x86_64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_dbr_regnums_x86_64) / sizeof(g_dbr_regnums_x86_64[0])) -
+ 1 ==
+ k_num_dbr_registers_x86_64,
+ "g_dbr_regnums_x86_64 has wrong number of register infos");
+
+// x86 32-bit general purpose registers.
+static const uint32_t g_gpr_regnums_i386[] = {
+ lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386,
+ lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386,
+ lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386,
+ lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386,
+ lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386,
+ lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386,
+ lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386,
+ lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
+ 1 ==
+ k_num_gpr_registers_i386,
+ "g_gpr_regnums_i386 has wrong number of register infos");
+
+// x86 32-bit floating point registers.
+static const uint32_t g_fpu_regnums_i386[] = {
+ lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386,
+ lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386,
+ lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386,
+ lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386,
+ lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386,
+ lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386,
+ lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386,
+ lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386,
+ lldb_xmm6_i386, lldb_xmm7_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) -
+ 1 ==
+ k_num_fpr_registers_i386,
+ "g_fpu_regnums_i386 has wrong number of register infos");
+
+static const uint32_t g_avx_regnums_i386[] = {
+ lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
+ lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -
+ 1 ==
+ k_num_avx_registers_i386,
+ "g_avx_regnums_i386 has wrong number of register infos");
+
+static const uint32_t g_mpx_regnums_i386[] = {
+ // Note: we currently do not provide them but this is needed to avoid
+ // unnamed groups in SBFrame::GetRegisterContext().
+ lldb_bnd0_i386, lldb_bnd1_i386, lldb_bnd2_i386,
+ lldb_bnd3_i386, lldb_bndcfgu_i386, lldb_bndstatus_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_mpx_regnums_i386) / sizeof(g_mpx_regnums_i386[0])) -
+ 1 ==
+ k_num_mpx_registers_i386,
+ "g_mpx_regnums_i386 has wrong number of register infos");
+
+// x86 debug registers.
+static const uint32_t g_dbr_regnums_i386[] = {
+ lldb_dr0_i386, lldb_dr1_i386, lldb_dr2_i386, lldb_dr3_i386,
+ lldb_dr4_i386, lldb_dr5_i386, lldb_dr6_i386, lldb_dr7_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_dbr_regnums_i386) / sizeof(g_dbr_regnums_i386[0])) -
+ 1 ==
+ k_num_dbr_registers_i386,
+ "g_dbr_regnums_i386 has wrong number of register infos");
+
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 5 };
+
+// Register sets for x86 32-bit.
+static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
+ g_gpr_regnums_i386},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
+ g_fpu_regnums_i386},
+ {"Debug Registers", "dbr", k_num_dbr_registers_i386, g_dbr_regnums_i386},
+ {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
+ g_avx_regnums_i386},
+ {"Memory Protection Extensions", "mpx", k_num_mpx_registers_i386,
+ g_mpx_regnums_i386},
+};
+
+// Register sets for x86 64-bit.
+static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64,
+ g_gpr_regnums_x86_64},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64,
+ g_fpu_regnums_x86_64},
+ {"Debug Registers", "dbr", k_num_dbr_registers_x86_64,
+ g_dbr_regnums_x86_64},
+ {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64,
+ g_avx_regnums_x86_64},
+ {"Memory Protection Extensions", "mpx", k_num_mpx_registers_x86_64,
+ g_mpx_regnums_x86_64},
+};
+
+#define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize())
+
+NativeRegisterContextFreeBSD *
+NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return new NativeRegisterContextFreeBSD_x86_64(target_arch, native_thread);
+}
+
+// NativeRegisterContextFreeBSD_x86_64 members.
+
+static RegisterInfoInterface *
+CreateRegisterInfoInterface(const ArchSpec &target_arch) {
+ if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
+ // 32-bit hosts run with a RegisterContextFreeBSD_i386 context.
+ return new RegisterContextFreeBSD_i386(target_arch);
+ } else {
+ assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
+ "Register setting path assumes this is a 64-bit host");
+ // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the
+ // x86_64 register context.
+ return new RegisterContextFreeBSD_x86_64(target_arch);
+ }
+}
+
+NativeRegisterContextFreeBSD_x86_64::NativeRegisterContextFreeBSD_x86_64(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextRegisterInfo(
+ native_thread, CreateRegisterInfoInterface(target_arch)),
+ m_regset_offsets({0}) {
+ assert(m_gpr.size() == GetRegisterInfoInterface().GetGPRSize());
+ std::array<uint32_t, MaxRegSet + 1> first_regnos;
+
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::x86:
+ first_regnos[FPRegSet] = lldb_fctrl_i386;
+ first_regnos[DBRegSet] = lldb_dr0_i386;
+ break;
+ case llvm::Triple::x86_64:
+ first_regnos[FPRegSet] = lldb_fctrl_x86_64;
+ first_regnos[DBRegSet] = lldb_dr0_x86_64;
+ break;
+ default:
+ llvm_unreachable("Unhandled target architecture.");
+ }
+
+ for (int i : {FPRegSet, DBRegSet})
+ m_regset_offsets[i] = GetRegisterInfoInterface()
+ .GetRegisterInfo()[first_regnos[i]]
+ .byte_offset;
+}
+
+uint32_t NativeRegisterContextFreeBSD_x86_64::GetRegisterSetCount() const {
+ return k_num_register_sets;
+}
+
+const RegisterSet *
+NativeRegisterContextFreeBSD_x86_64::GetRegisterSet(uint32_t set_index) const {
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::x86:
+ return &g_reg_sets_i386[set_index];
+ case llvm::Triple::x86_64:
+ return &g_reg_sets_x86_64[set_index];
+ default:
+ llvm_unreachable("Unhandled target architecture.");
+ }
+}
+
+llvm::Optional<NativeRegisterContextFreeBSD_x86_64::RegSetKind>
+NativeRegisterContextFreeBSD_x86_64::GetSetForNativeRegNum(
+ uint32_t reg_num) const {
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::x86:
+ if (reg_num >= k_first_gpr_i386 && reg_num <= k_last_gpr_i386)
+ return GPRegSet;
+ if (reg_num >= k_first_fpr_i386 && reg_num <= k_last_fpr_i386)
+ return FPRegSet;
+ if (reg_num >= k_first_avx_i386 && reg_num <= k_last_avx_i386)
+ return YMMRegSet;
+ if (reg_num >= k_first_mpxr_i386 && reg_num <= k_last_mpxr_i386)
+ return llvm::None; // MPXR
+ if (reg_num >= k_first_mpxc_i386 && reg_num <= k_last_mpxc_i386)
+ return llvm::None; // MPXC
+ if (reg_num >= k_first_dbr_i386 && reg_num <= k_last_dbr_i386)
+ return DBRegSet; // DBR
+ break;
+ case llvm::Triple::x86_64:
+ if (reg_num >= k_first_gpr_x86_64 && reg_num <= k_last_gpr_x86_64)
+ return GPRegSet;
+ if (reg_num >= k_first_fpr_x86_64 && reg_num <= k_last_fpr_x86_64)
+ return FPRegSet;
+ if (reg_num >= k_first_avx_x86_64 && reg_num <= k_last_avx_x86_64)
+ return YMMRegSet;
+ if (reg_num >= k_first_mpxr_x86_64 && reg_num <= k_last_mpxr_x86_64)
+ return llvm::None; // MPXR
+ if (reg_num >= k_first_mpxc_x86_64 && reg_num <= k_last_mpxc_x86_64)
+ return llvm::None; // MPXC
+ if (reg_num >= k_first_dbr_x86_64 && reg_num <= k_last_dbr_x86_64)
+ return DBRegSet; // DBR
+ break;
+ default:
+ llvm_unreachable("Unhandled target architecture.");
+ }
+
+ llvm_unreachable("Register does not belong to any register set");
+}
+
+Status NativeRegisterContextFreeBSD_x86_64::ReadRegisterSet(RegSetKind set) {
+ switch (set) {
+ case GPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(),
+ m_gpr.data());
+ case FPRegSet:
+#if defined(__x86_64__)
+ return NativeProcessFreeBSD::PtraceWrapper(PT_GETFPREGS, m_thread.GetID(),
+ m_fpr.data());
+#else
+ return NativeProcessFreeBSD::PtraceWrapper(PT_GETXMMREGS, m_thread.GetID(),
+ m_fpr.data());
+#endif
+ case DBRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_GETDBREGS, m_thread.GetID(),
+ m_dbr.data());
+ case YMMRegSet:
+ case MPXRegSet: {
+ struct ptrace_xstate_info info;
+ Status ret = NativeProcessFreeBSD::PtraceWrapper(
+ PT_GETXSTATE_INFO, GetProcessPid(), &info, sizeof(info));
+ if (!ret.Success())
+ return ret;
+
+ assert(info.xsave_mask & XFEATURE_ENABLED_X87);
+ assert(info.xsave_mask & XFEATURE_ENABLED_SSE);
+
+ m_xsave_offsets[YMMRegSet] = LLDB_INVALID_XSAVE_OFFSET;
+ if (info.xsave_mask & XFEATURE_ENABLED_YMM_HI128) {
+ uint32_t eax, ecx, edx;
+ __get_cpuid_count(0x0D, 2, &eax, &m_xsave_offsets[YMMRegSet], &ecx, &edx);
+ }
+
+ m_xsave.resize(info.xsave_len);
+ return NativeProcessFreeBSD::PtraceWrapper(PT_GETXSTATE, GetProcessPid(),
+ m_xsave.data(), m_xsave.size());
+ }
+ }
+ llvm_unreachable("NativeRegisterContextFreeBSD_x86_64::ReadRegisterSet");
+}
+
+Status NativeRegisterContextFreeBSD_x86_64::WriteRegisterSet(RegSetKind set) {
+ switch (set) {
+ case GPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(),
+ m_gpr.data());
+ case FPRegSet:
+#if defined(__x86_64__)
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETFPREGS, m_thread.GetID(),
+ m_fpr.data());
+#else
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETXMMREGS, m_thread.GetID(),
+ m_fpr.data());
+#endif
+ case DBRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETDBREGS, m_thread.GetID(),
+ m_dbr.data());
+ case YMMRegSet:
+ case MPXRegSet:
+ // ReadRegisterSet() must always be called before WriteRegisterSet().
+ assert(m_xsave.size() > 0);
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETXSTATE, GetProcessPid(),
+ m_xsave.data(), m_xsave.size());
+ }
+ llvm_unreachable("NativeRegisterContextFreeBSD_x86_64::WriteRegisterSet");
+}
+
+Status
+NativeRegisterContextFreeBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ Status error;
+
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
+ "register, cannot read directly",
+ reg_info->name);
+ return error;
+ }
+
+ llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);
+ if (!opt_set) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
+ reg_info->name);
+ return error;
+ }
+
+ RegSetKind set = opt_set.getValue();
+ error = ReadRegisterSet(set);
+ if (error.Fail())
+ return error;
+
+ switch (set) {
+ case GPRegSet:
+ case FPRegSet:
+ case DBRegSet: {
+ void *data = GetOffsetRegSetData(set, reg_info->byte_offset);
+ FXSAVE *fpr = reinterpret_cast<FXSAVE *>(m_fpr.data());
+ if (data == &fpr->ftag) // ftag
+ reg_value.SetUInt16(
+ AbridgedToFullTagWord(fpr->ftag, fpr->fstat, fpr->stmm));
+ else
+ reg_value.SetBytes(data, reg_info->byte_size, endian::InlHostByteOrder());
+ break;
+ }
+ case YMMRegSet: {
+ llvm::Optional<YMMSplitPtr> ymm_reg = GetYMMSplitReg(reg);
+ if (!ymm_reg) {
+ error.SetErrorStringWithFormat(
+ "register \"%s\" not supported by CPU/kernel", reg_info->name);
+ } else {
+ YMMReg ymm = XStateToYMM(ymm_reg->xmm, ymm_reg->ymm_hi);
+ reg_value.SetBytes(ymm.bytes, reg_info->byte_size,
+ endian::InlHostByteOrder());
+ }
+ break;
+ }
+ case MPXRegSet:
+ llvm_unreachable("MPX regset should have returned error");
+ }
+
+ return error;
+}
+
+Status NativeRegisterContextFreeBSD_x86_64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+
+ Status error;
+
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
+ "register, cannot read directly",
+ reg_info->name);
+ return error;
+ }
+
+ llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);
+ if (!opt_set) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
+ reg_info->name);
+ return error;
+ }
+
+ RegSetKind set = opt_set.getValue();
+ error = ReadRegisterSet(set);
+ if (error.Fail())
+ return error;
+
+ switch (set) {
+ case GPRegSet:
+ case FPRegSet:
+ case DBRegSet: {
+ void *data = GetOffsetRegSetData(set, reg_info->byte_offset);
+ FXSAVE *fpr = reinterpret_cast<FXSAVE *>(m_fpr.data());
+ if (data == &fpr->ftag) // ftag
+ fpr->ftag = FullToAbridgedTagWord(reg_value.GetAsUInt16());
+ else
+ ::memcpy(data, reg_value.GetBytes(), reg_value.GetByteSize());
+ break;
+ }
+ case YMMRegSet: {
+ llvm::Optional<YMMSplitPtr> ymm_reg = GetYMMSplitReg(reg);
+ if (!ymm_reg) {
+ error.SetErrorStringWithFormat(
+ "register \"%s\" not supported by CPU/kernel", reg_info->name);
+ } else {
+ YMMReg ymm;
+ ::memcpy(ymm.bytes, reg_value.GetBytes(), reg_value.GetByteSize());
+ YMMToXState(ymm, ymm_reg->xmm, ymm_reg->ymm_hi);
+ }
+ break;
+ }
+ case MPXRegSet:
+ llvm_unreachable("MPX regset should have returned error");
+ }
+
+ return WriteRegisterSet(set);
+}
+
+Status NativeRegisterContextFreeBSD_x86_64::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ error = ReadRegisterSet(GPRegSet);
+ if (error.Fail())
+ return error;
+
+ uint8_t *dst = data_sp->GetBytes();
+ ::memcpy(dst, m_gpr.data(), GetRegisterInfoInterface().GetGPRSize());
+ dst += GetRegisterInfoInterface().GetGPRSize();
+
+ return error;
+}
+
+Status NativeRegisterContextFreeBSD_x86_64::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextFreeBSD_x86_64::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
+
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextFreeBSD_x86_64::%s data_sp contained mismatched "
+ "data size, expected %zu, actual %" PRIu64,
+ __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_x86_64::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ ::memcpy(m_gpr.data(), src, GetRegisterInfoInterface().GetGPRSize());
+
+ error = WriteRegisterSet(GPRegSet);
+ if (error.Fail())
+ return error;
+ src += GetRegisterInfoInterface().GetGPRSize();
+
+ return error;
+}
+
+llvm::Error NativeRegisterContextFreeBSD_x86_64::CopyHardwareWatchpointsFrom(
+ NativeRegisterContextFreeBSD &source) {
+ auto &r_source = static_cast<NativeRegisterContextFreeBSD_x86_64 &>(source);
+ // NB: This implicitly reads the whole dbreg set.
+ RegisterValue dr7;
+ Status res = r_source.ReadRegister(GetDR(7), dr7);
+ if (!res.Fail()) {
+ // copy dbregs only if any watchpoints were set
+ if ((dr7.GetAsUInt64() & 0xFF) == 0)
+ return llvm::Error::success();
+
+ m_dbr = r_source.m_dbr;
+ res = WriteRegisterSet(DBRegSet);
+ }
+ return res.ToError();
+}
+
+uint8_t *
+NativeRegisterContextFreeBSD_x86_64::GetOffsetRegSetData(RegSetKind set,
+ size_t reg_offset) {
+ uint8_t *base;
+ switch (set) {
+ case GPRegSet:
+ base = m_gpr.data();
+ break;
+ case FPRegSet:
+ base = m_fpr.data();
+ break;
+ case DBRegSet:
+ base = m_dbr.data();
+ break;
+ case YMMRegSet:
+ llvm_unreachable("GetRegSetData() is unsuitable for this regset.");
+ case MPXRegSet:
+ llvm_unreachable("MPX regset should have returned error");
+ }
+ assert(reg_offset >= m_regset_offsets[set]);
+ return base + (reg_offset - m_regset_offsets[set]);
+}
+
+llvm::Optional<NativeRegisterContextFreeBSD_x86_64::YMMSplitPtr>
+NativeRegisterContextFreeBSD_x86_64::GetYMMSplitReg(uint32_t reg) {
+ uint32_t offset = m_xsave_offsets[YMMRegSet];
+ if (offset == LLDB_INVALID_XSAVE_OFFSET)
+ return llvm::None;
+
+ uint32_t reg_index;
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::x86:
+ reg_index = reg - lldb_ymm0_i386;
+ break;
+ case llvm::Triple::x86_64:
+ reg_index = reg - lldb_ymm0_x86_64;
+ break;
+ default:
+ llvm_unreachable("Unhandled target architecture.");
+ }
+
+ auto *fpreg = reinterpret_cast<struct savexmm_ymm *>(m_xsave.data());
+ auto *ymmreg = reinterpret_cast<struct ymmacc *>(m_xsave.data() + offset);
+
+ return YMMSplitPtr{&fpreg->sv_xmm[reg_index], &ymmreg[reg_index]};
+}
+
+#endif // defined(__x86_64__)
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h
new file mode 100644
index 000000000000..efd0f91f77b9
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h
@@ -0,0 +1,96 @@
+//===-- NativeRegisterContextFreeBSD_x86_64.h -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__i386__) || defined(__x86_64__)
+
+#ifndef lldb_NativeRegisterContextFreeBSD_x86_64_h
+#define lldb_NativeRegisterContextFreeBSD_x86_64_h
+
+// clang-format off
+#include <sys/param.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+#include <machine/reg.h>
+// clang-format on
+
+#include <array>
+
+#include "Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h"
+#include "Plugins/Process/Utility/RegisterContext_x86.h"
+#include "Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h"
+#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
+
+#define LLDB_INVALID_XSAVE_OFFSET UINT32_MAX
+
+namespace lldb_private {
+namespace process_freebsd {
+
+class NativeProcessFreeBSD;
+
+class NativeRegisterContextFreeBSD_x86_64
+ : public NativeRegisterContextFreeBSD,
+ public NativeRegisterContextDBReg_x86 {
+public:
+ NativeRegisterContextFreeBSD_x86_64(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread);
+ uint32_t GetRegisterSetCount() const override;
+
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
+
+ Status ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
+
+ Status WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
+
+ Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ llvm::Error
+ CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) override;
+
+private:
+ // Private member types.
+ enum RegSetKind {
+ GPRegSet,
+ FPRegSet,
+ DBRegSet,
+ YMMRegSet,
+ MPXRegSet,
+ MaxRegSet = MPXRegSet,
+ };
+
+ // Private member variables.
+ std::array<uint8_t, sizeof(struct reg)> m_gpr;
+ std::array<uint8_t, 512> m_fpr; // FXSAVE
+ std::array<uint8_t, sizeof(struct dbreg)> m_dbr;
+ std::vector<uint8_t> m_xsave;
+ std::array<uint32_t, MaxRegSet + 1> m_xsave_offsets;
+ std::array<size_t, MaxRegSet + 1> m_regset_offsets;
+
+ llvm::Optional<RegSetKind> GetSetForNativeRegNum(uint32_t reg_num) const;
+
+ Status ReadRegisterSet(RegSetKind set);
+ Status WriteRegisterSet(RegSetKind set);
+
+ uint8_t *GetOffsetRegSetData(RegSetKind set, size_t reg_offset);
+
+ struct YMMSplitPtr {
+ void *xmm;
+ void *ymm_hi;
+ };
+ llvm::Optional<YMMSplitPtr> GetYMMSplitReg(uint32_t reg);
+};
+
+} // namespace process_freebsd
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextFreeBSD_x86_64_h
+
+#endif // defined(__x86_64__)
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
new file mode 100644
index 000000000000..63be12fc7b2b
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
@@ -0,0 +1,291 @@
+//===-- NativeThreadFreeBSD.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeThreadFreeBSD.h"
+#include "NativeRegisterContextFreeBSD.h"
+
+#include "NativeProcessFreeBSD.h"
+
+#include "Plugins/Process/POSIX/CrashReason.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/State.h"
+#include "llvm/Support/Errno.h"
+
+// clang-format off
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/sysctl.h>
+#include <sys/user.h>
+// clang-format on
+
+#include <sstream>
+#include <vector>
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_freebsd;
+
+NativeThreadFreeBSD::NativeThreadFreeBSD(NativeProcessFreeBSD &process,
+ lldb::tid_t tid)
+ : NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
+ m_stop_info(),
+ m_reg_context_up(
+ NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
+ process.GetArchitecture(), *this)),
+ m_stop_description() {}
+
+Status NativeThreadFreeBSD::Resume() {
+ Status ret = NativeProcessFreeBSD::PtraceWrapper(PT_RESUME, GetID());
+ if (!ret.Success())
+ return ret;
+ ret = NativeProcessFreeBSD::PtraceWrapper(PT_CLEARSTEP, GetID());
+ // we can get EINVAL if the architecture in question does not support
+ // hardware single-stepping -- that's fine, we have nothing to clear
+ // then
+ if (ret.GetError() == EINVAL)
+ ret.Clear();
+ if (ret.Success())
+ SetRunning();
+ return ret;
+}
+
+Status NativeThreadFreeBSD::SingleStep() {
+ Status ret = NativeProcessFreeBSD::PtraceWrapper(PT_RESUME, GetID());
+ if (!ret.Success())
+ return ret;
+ ret = NativeProcessFreeBSD::PtraceWrapper(PT_SETSTEP, GetID());
+ if (ret.Success())
+ SetStepping();
+ return ret;
+}
+
+Status NativeThreadFreeBSD::Suspend() {
+ Status ret = NativeProcessFreeBSD::PtraceWrapper(PT_SUSPEND, GetID());
+ if (ret.Success())
+ SetStopped();
+ return ret;
+}
+
+void NativeThreadFreeBSD::SetStoppedBySignal(uint32_t signo,
+ const siginfo_t *info) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ LLDB_LOG(log, "tid = {0} in called with signal {1}", GetID(), signo);
+
+ SetStopped();
+
+ m_stop_info.reason = StopReason::eStopReasonSignal;
+ m_stop_info.details.signal.signo = signo;
+
+ m_stop_description.clear();
+ if (info) {
+ switch (signo) {
+ case SIGSEGV:
+ case SIGBUS:
+ case SIGFPE:
+ case SIGILL:
+ const auto reason = GetCrashReason(*info);
+ m_stop_description = GetCrashReasonString(reason, *info);
+ break;
+ }
+ }
+}
+
+void NativeThreadFreeBSD::SetStoppedByBreakpoint() {
+ SetStopped();
+ m_stop_info.reason = StopReason::eStopReasonBreakpoint;
+ m_stop_info.details.signal.signo = SIGTRAP;
+}
+
+void NativeThreadFreeBSD::SetStoppedByTrace() {
+ SetStopped();
+ m_stop_info.reason = StopReason::eStopReasonTrace;
+ m_stop_info.details.signal.signo = SIGTRAP;
+}
+
+void NativeThreadFreeBSD::SetStoppedByExec() {
+ SetStopped();
+ m_stop_info.reason = StopReason::eStopReasonExec;
+ m_stop_info.details.signal.signo = SIGTRAP;
+}
+
+void NativeThreadFreeBSD::SetStoppedByWatchpoint(uint32_t wp_index) {
+ lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
+
+ std::ostringstream ostr;
+ ostr << GetRegisterContext().GetWatchpointAddress(wp_index) << " ";
+ ostr << wp_index;
+
+ ostr << " " << GetRegisterContext().GetWatchpointHitAddress(wp_index);
+
+ SetStopped();
+ m_stop_description = ostr.str();
+ m_stop_info.reason = StopReason::eStopReasonWatchpoint;
+ m_stop_info.details.signal.signo = SIGTRAP;
+}
+
+void NativeThreadFreeBSD::SetStoppedWithNoReason() {
+ SetStopped();
+
+ m_stop_info.reason = StopReason::eStopReasonNone;
+ m_stop_info.details.signal.signo = 0;
+}
+
+void NativeThreadFreeBSD::SetStopped() {
+ const StateType new_state = StateType::eStateStopped;
+ m_state = new_state;
+ m_stop_description.clear();
+}
+
+void NativeThreadFreeBSD::SetRunning() {
+ m_state = StateType::eStateRunning;
+ m_stop_info.reason = StopReason::eStopReasonNone;
+}
+
+void NativeThreadFreeBSD::SetStepping() {
+ m_state = StateType::eStateStepping;
+ m_stop_info.reason = StopReason::eStopReasonNone;
+}
+
+std::string NativeThreadFreeBSD::GetName() {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+
+ std::vector<struct kinfo_proc> kp;
+ int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD,
+ static_cast<int>(GetProcess().GetID())};
+
+ while (1) {
+ size_t len = kp.size() * sizeof(struct kinfo_proc);
+ void *ptr = len == 0 ? nullptr : kp.data();
+ int error = ::sysctl(mib, 4, ptr, &len, nullptr, 0);
+ if (ptr == nullptr || (error != 0 && errno == ENOMEM)) {
+ kp.resize(len / sizeof(struct kinfo_proc));
+ continue;
+ }
+ if (error != 0) {
+ len = 0;
+ LLDB_LOG(log, "tid = {0} in state {1} failed to get thread name: {2}",
+ GetID(), m_state, strerror(errno));
+ }
+ kp.resize(len / sizeof(struct kinfo_proc));
+ break;
+ }
+
+ for (auto &procinfo : kp) {
+ if (procinfo.ki_tid == static_cast<lwpid_t>(GetID()))
+ return procinfo.ki_tdname;
+ }
+
+ return "";
+}
+
+lldb::StateType NativeThreadFreeBSD::GetState() { return m_state; }
+
+bool NativeThreadFreeBSD::GetStopReason(ThreadStopInfo &stop_info,
+ std::string &description) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+ description.clear();
+
+ switch (m_state) {
+ case eStateStopped:
+ case eStateCrashed:
+ case eStateExited:
+ case eStateSuspended:
+ case eStateUnloaded:
+ stop_info = m_stop_info;
+ description = m_stop_description;
+
+ return true;
+
+ case eStateInvalid:
+ case eStateConnected:
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateRunning:
+ case eStateStepping:
+ case eStateDetached:
+ LLDB_LOG(log, "tid = {0} in state {1} cannot answer stop reason", GetID(),
+ StateAsCString(m_state));
+ return false;
+ }
+ llvm_unreachable("unhandled StateType!");
+}
+
+NativeRegisterContextFreeBSD &NativeThreadFreeBSD::GetRegisterContext() {
+ assert(m_reg_context_up);
+ return *m_reg_context_up;
+}
+
+Status NativeThreadFreeBSD::SetWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags, bool hardware) {
+ assert(m_state == eStateStopped);
+ if (!hardware)
+ return Status("not implemented");
+ Status error = RemoveWatchpoint(addr);
+ if (error.Fail())
+ return error;
+ uint32_t wp_index =
+ GetRegisterContext().SetHardwareWatchpoint(addr, size, watch_flags);
+ if (wp_index == LLDB_INVALID_INDEX32)
+ return Status("Setting hardware watchpoint failed.");
+ m_watchpoint_index_map.insert({addr, wp_index});
+ return Status();
+}
+
+Status NativeThreadFreeBSD::RemoveWatchpoint(lldb::addr_t addr) {
+ auto wp = m_watchpoint_index_map.find(addr);
+ if (wp == m_watchpoint_index_map.end())
+ return Status();
+ uint32_t wp_index = wp->second;
+ m_watchpoint_index_map.erase(wp);
+ if (GetRegisterContext().ClearHardwareWatchpoint(wp_index))
+ return Status();
+ return Status("Clearing hardware watchpoint failed.");
+}
+
+Status NativeThreadFreeBSD::SetHardwareBreakpoint(lldb::addr_t addr,
+ size_t size) {
+ assert(m_state == eStateStopped);
+ Status error = RemoveHardwareBreakpoint(addr);
+ if (error.Fail())
+ return error;
+
+ uint32_t bp_index = GetRegisterContext().SetHardwareBreakpoint(addr, size);
+
+ if (bp_index == LLDB_INVALID_INDEX32)
+ return Status("Setting hardware breakpoint failed.");
+
+ m_hw_break_index_map.insert({addr, bp_index});
+ return Status();
+}
+
+Status NativeThreadFreeBSD::RemoveHardwareBreakpoint(lldb::addr_t addr) {
+ auto bp = m_hw_break_index_map.find(addr);
+ if (bp == m_hw_break_index_map.end())
+ return Status();
+
+ uint32_t bp_index = bp->second;
+ if (GetRegisterContext().ClearHardwareBreakpoint(bp_index)) {
+ m_hw_break_index_map.erase(bp);
+ return Status();
+ }
+
+ return Status("Clearing hardware breakpoint failed.");
+}
+
+llvm::Error
+NativeThreadFreeBSD::CopyWatchpointsFrom(NativeThreadFreeBSD &source) {
+ llvm::Error s = GetRegisterContext().CopyHardwareWatchpointsFrom(
+ source.GetRegisterContext());
+ if (!s) {
+ m_watchpoint_index_map = source.m_watchpoint_index_map;
+ m_hw_break_index_map = source.m_hw_break_index_map;
+ }
+ return s;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
new file mode 100644
index 000000000000..249d2486b4f7
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
@@ -0,0 +1,83 @@
+//===-- NativeThreadFreeBSD.h --------------------------------- -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_NativeThreadFreeBSD_H_
+#define liblldb_NativeThreadFreeBSD_H_
+
+#include "lldb/Host/common/NativeThreadProtocol.h"
+
+#include "Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h"
+
+#include <csignal>
+#include <map>
+#include <string>
+
+namespace lldb_private {
+namespace process_freebsd {
+
+class NativeProcessFreeBSD;
+
+class NativeThreadFreeBSD : public NativeThreadProtocol {
+ friend class NativeProcessFreeBSD;
+
+public:
+ NativeThreadFreeBSD(NativeProcessFreeBSD &process, lldb::tid_t tid);
+
+ // NativeThreadProtocol Interface
+ std::string GetName() override;
+
+ lldb::StateType GetState() override;
+
+ bool GetStopReason(ThreadStopInfo &stop_info,
+ std::string &description) override;
+
+ NativeRegisterContextFreeBSD &GetRegisterContext() override;
+
+ Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
+ bool hardware) override;
+
+ Status RemoveWatchpoint(lldb::addr_t addr) override;
+
+ Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
+
+ Status RemoveHardwareBreakpoint(lldb::addr_t addr) override;
+
+private:
+ // Interface for friend classes
+
+ Status Resume();
+ Status SingleStep();
+ Status Suspend();
+
+ void SetStoppedBySignal(uint32_t signo, const siginfo_t *info = nullptr);
+ void SetStoppedByBreakpoint();
+ void SetStoppedByTrace();
+ void SetStoppedByExec();
+ void SetStoppedByWatchpoint(uint32_t wp_index);
+ void SetStoppedWithNoReason();
+ void SetStopped();
+ void SetRunning();
+ void SetStepping();
+
+ llvm::Error CopyWatchpointsFrom(NativeThreadFreeBSD &source);
+
+ // Member Variables
+ lldb::StateType m_state;
+ ThreadStopInfo m_stop_info;
+ std::unique_ptr<NativeRegisterContextFreeBSD> m_reg_context_up;
+ std::string m_stop_description;
+ using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
+ WatchpointIndexMap m_watchpoint_index_map;
+ WatchpointIndexMap m_hw_break_index_map;
+};
+
+typedef std::shared_ptr<NativeThreadFreeBSD> NativeThreadFreeBSDSP;
+} // namespace process_freebsd
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_NativeThreadFreeBSD_H_
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
deleted file mode 100644
index 4e6f3afda0ab..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-//===-- POSIXStopInfo.cpp -------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "POSIXStopInfo.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//===----------------------------------------------------------------------===//
-// POSIXLimboStopInfo
-
-POSIXLimboStopInfo::~POSIXLimboStopInfo() {}
-
-lldb::StopReason POSIXLimboStopInfo::GetStopReason() const {
- return lldb::eStopReasonThreadExiting;
-}
-
-const char *POSIXLimboStopInfo::GetDescription() { return "thread exiting"; }
-
-bool POSIXLimboStopInfo::ShouldStop(Event *event_ptr) { return false; }
-
-bool POSIXLimboStopInfo::ShouldNotify(Event *event_ptr) { return false; }
-
-//===----------------------------------------------------------------------===//
-// POSIXNewThreadStopInfo
-
-POSIXNewThreadStopInfo::~POSIXNewThreadStopInfo() {}
-
-lldb::StopReason POSIXNewThreadStopInfo::GetStopReason() const {
- return lldb::eStopReasonNone;
-}
-
-const char *POSIXNewThreadStopInfo::GetDescription() {
- return "thread spawned";
-}
-
-bool POSIXNewThreadStopInfo::ShouldStop(Event *event_ptr) { return false; }
-
-bool POSIXNewThreadStopInfo::ShouldNotify(Event *event_ptr) { return false; }
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
deleted file mode 100644
index 88fb7f31fe06..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//===-- POSIXStopInfo.h -----------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_POSIXStopInfo_H_
-#define liblldb_POSIXStopInfo_H_
-
-#include "FreeBSDThread.h"
-#include "Plugins/Process/POSIX/CrashReason.h"
-#include "lldb/Target/StopInfo.h"
-#include <string>
-
-//===----------------------------------------------------------------------===//
-/// \class POSIXStopInfo
-/// Simple base class for all POSIX-specific StopInfo objects.
-///
-class POSIXStopInfo : public lldb_private::StopInfo {
-public:
- POSIXStopInfo(lldb_private::Thread &thread, uint32_t status)
- : StopInfo(thread, status) {}
-};
-
-//===----------------------------------------------------------------------===//
-/// \class POSIXLimboStopInfo
-/// Represents the stop state of a process ready to exit.
-///
-class POSIXLimboStopInfo : public POSIXStopInfo {
-public:
- POSIXLimboStopInfo(FreeBSDThread &thread) : POSIXStopInfo(thread, 0) {}
-
- ~POSIXLimboStopInfo();
-
- lldb::StopReason GetStopReason() const;
-
- const char *GetDescription();
-
- bool ShouldStop(lldb_private::Event *event_ptr);
-
- bool ShouldNotify(lldb_private::Event *event_ptr);
-};
-
-//===----------------------------------------------------------------------===//
-/// \class POSIXNewThreadStopInfo
-/// Represents the stop state of process when a new thread is spawned.
-///
-
-class POSIXNewThreadStopInfo : public POSIXStopInfo {
-public:
- POSIXNewThreadStopInfo(FreeBSDThread &thread) : POSIXStopInfo(thread, 0) {}
-
- ~POSIXNewThreadStopInfo();
-
- lldb::StopReason GetStopReason() const;
-
- const char *GetDescription();
-
- bool ShouldStop(lldb_private::Event *event_ptr);
-
- bool ShouldNotify(lldb_private::Event *event_ptr);
-};
-
-#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
deleted file mode 100644
index a44080640f6c..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
+++ /dev/null
@@ -1,1077 +0,0 @@
-//===-- ProcessFreeBSD.cpp ------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include <errno.h>
-#include <pthread.h>
-#include <pthread_np.h>
-#include <stdlib.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-#include <sys/user.h>
-#include <machine/elf.h>
-
-#include <mutex>
-#include <unordered_map>
-
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/State.h"
-
-#include "FreeBSDThread.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/FreeBSDSignals.h"
-#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
-#include "ProcessFreeBSD.h"
-#include "ProcessMonitor.h"
-
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/Platform.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/State.h"
-
-#include "lldb/Host/posix/Fcntl.h"
-
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Threading.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-LLDB_PLUGIN_DEFINE(ProcessFreeBSD)
-
-namespace {
-UnixSignalsSP &GetFreeBSDSignals() {
- static UnixSignalsSP s_freebsd_signals_sp(new FreeBSDSignals());
- return s_freebsd_signals_sp;
-}
-}
-
-// Static functions.
-
-lldb::ProcessSP
-ProcessFreeBSD::CreateInstance(lldb::TargetSP target_sp,
- 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_sp, GetFreeBSDSignals()));
- return process_sp;
-}
-
-void ProcessFreeBSD::Initialize() {
- static llvm::once_flag g_once_flag;
-
- llvm::call_once(g_once_flag, []() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(), CreateInstance);
- });
-}
-
-lldb_private::ConstString ProcessFreeBSD::GetPluginNameStatic() {
- static ConstString g_name("freebsd");
- return g_name;
-}
-
-const char *ProcessFreeBSD::GetPluginDescriptionStatic() {
- return "Process plugin for FreeBSD";
-}
-
-// ProcessInterface protocol.
-
-lldb_private::ConstString ProcessFreeBSD::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t ProcessFreeBSD::GetPluginVersion() { return 1; }
-
-void ProcessFreeBSD::Terminate() {}
-
-Status ProcessFreeBSD::DoDetach(bool keep_stopped) {
- Status error;
- if (keep_stopped) {
- error.SetErrorString("Detaching with keep_stopped true is not currently "
- "supported on FreeBSD.");
- return error;
- }
-
- error = m_monitor->Detach(GetID());
-
- if (error.Success())
- SetPrivateState(eStateDetached);
-
- return error;
-}
-
-Status ProcessFreeBSD::DoResume() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- SetPrivateState(eStateRunning);
-
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- bool do_step = false;
- bool software_single_step = !SupportHardwareSingleStepping();
-
- for (tid_collection::const_iterator t_pos = m_run_tids.begin(),
- t_end = m_run_tids.end();
- t_pos != t_end; ++t_pos) {
- m_monitor->ThreadSuspend(*t_pos, false);
- }
- for (tid_collection::const_iterator t_pos = m_step_tids.begin(),
- t_end = m_step_tids.end();
- t_pos != t_end; ++t_pos) {
- m_monitor->ThreadSuspend(*t_pos, false);
- do_step = true;
- if (software_single_step) {
- Status error = SetupSoftwareSingleStepping(*t_pos);
- if (error.Fail())
- return error;
- }
- }
- for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(),
- t_end = m_suspend_tids.end();
- t_pos != t_end; ++t_pos) {
- m_monitor->ThreadSuspend(*t_pos, true);
- // XXX Cannot PT_CONTINUE properly with suspended threads.
- do_step = true;
- }
-
- LLDB_LOGF(log, "process %" PRIu64 " resuming (%s)", GetID(),
- do_step ? "step" : "continue");
- if (do_step && !software_single_step)
- m_monitor->SingleStep(GetID(), m_resume_signo);
- else
- m_monitor->Resume(GetID(), m_resume_signo);
-
- return Status();
-}
-
-bool ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list,
- ThreadList &new_thread_list) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOGF(log, "ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__,
- GetID());
-
- std::vector<lldb::pid_t> tds;
- if (!GetMonitor().GetCurrentThreadIDs(tds)) {
- return false;
- }
-
- ThreadList old_thread_list_copy(old_thread_list);
- for (size_t i = 0; i < tds.size(); ++i) {
- tid_t tid = tds[i];
- ThreadSP thread_sp(old_thread_list_copy.RemoveThreadByID(tid, false));
- if (!thread_sp) {
- thread_sp.reset(new FreeBSDThread(*this, tid));
- LLDB_LOGF(log, "ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__,
- tid);
- } else {
- LLDB_LOGF(log, "ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__,
- tid);
- }
- new_thread_list.AddThread(thread_sp);
- }
- for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i) {
- ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));
- if (old_thread_sp) {
- LLDB_LOGF(log, "ProcessFreeBSD::%s remove tid", __FUNCTION__);
- }
- }
-
- return true;
-}
-
-Status ProcessFreeBSD::WillResume() {
- m_resume_signo = 0;
- m_suspend_tids.clear();
- m_run_tids.clear();
- m_step_tids.clear();
- return Process::WillResume();
-}
-
-void ProcessFreeBSD::SendMessage(const ProcessMessage &message) {
- std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
-
- switch (message.GetKind()) {
- case ProcessMessage::eInvalidMessage:
- return;
-
- case ProcessMessage::eAttachMessage:
- SetPrivateState(eStateStopped);
- return;
-
- case ProcessMessage::eLimboMessage:
- case ProcessMessage::eExitMessage:
- SetExitStatus(message.GetExitStatus(), NULL);
- break;
-
- case ProcessMessage::eSignalMessage:
- case ProcessMessage::eSignalDeliveredMessage:
- case ProcessMessage::eBreakpointMessage:
- case ProcessMessage::eTraceMessage:
- case ProcessMessage::eWatchpointMessage:
- case ProcessMessage::eCrashMessage:
- SetPrivateState(eStateStopped);
- break;
-
- case ProcessMessage::eNewThreadMessage:
- llvm_unreachable("eNewThreadMessage unexpected on FreeBSD");
- break;
-
- case ProcessMessage::eExecMessage:
- SetPrivateState(eStateStopped);
- break;
- }
-
- m_message_queue.push(message);
-}
-
-// Constructors and destructors.
-
-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(), m_exit_now(false), m_seen_initial_stop(),
- m_resume_signo(0) {
- // FIXME: Putting this code in the ctor and saving the byte order in a
- // member variable is a hack to avoid const qual issues in GetByteOrder.
- lldb::ModuleSP module = GetTarget().GetExecutableModule();
- if (module && module->GetObjectFile())
- m_byte_order = module->GetObjectFile()->GetByteOrder();
-}
-
-ProcessFreeBSD::~ProcessFreeBSD() { delete m_monitor; }
-
-// Process protocol.
-void ProcessFreeBSD::Finalize() {
- Process::Finalize();
-
- if (m_monitor)
- m_monitor->StopMonitor();
-}
-
-bool ProcessFreeBSD::CanDebug(lldb::TargetSP target_sp,
- bool plugin_specified_by_name) {
- // For now we are just making sure the file exists for a given module
- ModuleSP exe_module_sp(target_sp->GetExecutableModule());
- if (exe_module_sp.get())
- return FileSystem::Instance().Exists(exe_module_sp->GetFileSpec());
- // If there is no executable module, we return true since we might be
- // preparing to attach.
- return true;
-}
-
-Status
-ProcessFreeBSD::DoAttachToProcessWithID(lldb::pid_t pid,
- const ProcessAttachInfo &attach_info) {
- Status error;
- assert(m_monitor == NULL);
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOGV(log, "pid = {0}", GetID());
-
- m_monitor = new ProcessMonitor(this, pid, error);
-
- if (!error.Success())
- return error;
-
- PlatformSP platform_sp(GetTarget().GetPlatform());
- assert(platform_sp.get());
- if (!platform_sp)
- return error; // FIXME: Detatch?
-
- // Find out what we can about this process
- ProcessInstanceInfo process_info;
- platform_sp->GetProcessInfo(pid, process_info);
-
- // Resolve the executable module
- ModuleSP exe_module_sp;
- FileSpecList executable_search_paths(
- Target::GetDefaultExecutableSearchPaths());
- ModuleSpec exe_module_spec(process_info.GetExecutableFile(),
- GetTarget().GetArchitecture());
- error = platform_sp->ResolveExecutable(
- exe_module_spec, exe_module_sp,
- executable_search_paths.GetSize() ? &executable_search_paths : NULL);
- if (!error.Success())
- return error;
-
- // Fix the target architecture if necessary
- const ArchSpec &module_arch = exe_module_sp->GetArchitecture();
- if (module_arch.IsValid() &&
- !GetTarget().GetArchitecture().IsExactMatch(module_arch))
- GetTarget().SetArchitecture(module_arch);
-
- // Initialize the target module list
- GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsYes);
-
- SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
-
- SetID(pid);
-
- return error;
-}
-
-Status ProcessFreeBSD::WillLaunch(Module *module) {
- Status error;
- return error;
-}
-
-FileSpec
-ProcessFreeBSD::GetFileSpec(const lldb_private::FileAction *file_action,
- const FileSpec &default_file_spec,
- const FileSpec &dbg_pts_file_spec) {
- FileSpec file_spec{};
-
- if (file_action && file_action->GetAction() == FileAction::eFileActionOpen) {
- file_spec = file_action->GetFileSpec();
- // By default the stdio paths passed in will be pseudo-terminal (/dev/pts).
- // If so, convert to using a different default path instead to redirect I/O
- // to the debugger console. This should also handle user overrides to
- // /dev/null or a different file.
- if (!file_spec || file_spec == dbg_pts_file_spec)
- file_spec = default_file_spec;
- }
- return file_spec;
-}
-
-Status ProcessFreeBSD::DoLaunch(Module *module,
- ProcessLaunchInfo &launch_info) {
- Status error;
- assert(m_monitor == NULL);
-
- FileSpec working_dir = launch_info.GetWorkingDirectory();
- if (working_dir) {
- FileSystem::Instance().Resolve(working_dir);
- if (!FileSystem::Instance().IsDirectory(working_dir.GetPath())) {
- error.SetErrorStringWithFormat("No such file or directory: %s",
- working_dir.GetCString());
- return error;
- }
- }
-
- SetPrivateState(eStateLaunching);
-
- const lldb_private::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{};
-
- const FileSpec dbg_pts_file_spec{
- launch_info.GetPTY().GetSecondaryName(NULL, 0)};
-
- file_action = launch_info.GetFileActionForFD(STDIN_FILENO);
- stdin_file_spec =
- GetFileSpec(file_action, stdin_file_spec, dbg_pts_file_spec);
-
- file_action = launch_info.GetFileActionForFD(STDOUT_FILENO);
- stdout_file_spec =
- GetFileSpec(file_action, stdout_file_spec, dbg_pts_file_spec);
-
- file_action = launch_info.GetFileActionForFD(STDERR_FILENO);
- stderr_file_spec =
- GetFileSpec(file_action, stderr_file_spec, dbg_pts_file_spec);
-
- m_monitor = new ProcessMonitor(
- this, module, launch_info.GetArguments().GetConstArgumentVector(),
- launch_info.GetEnvironment(), stdin_file_spec, stdout_file_spec,
- stderr_file_spec, working_dir, launch_info, error);
-
- m_module = module;
-
- if (!error.Success())
- return error;
-
- int terminal = m_monitor->GetTerminalFD();
- if (terminal >= 0) {
-// The reader thread will close the file descriptor when done, so we pass it a
-// copy.
-#ifdef F_DUPFD_CLOEXEC
- int stdio = fcntl(terminal, F_DUPFD_CLOEXEC, 0);
- if (stdio == -1) {
- error.SetErrorToErrno();
- return error;
- }
-#else
- // Special case when F_DUPFD_CLOEXEC does not exist (Debian kFreeBSD)
- int stdio = fcntl(terminal, F_DUPFD, 0);
- if (stdio == -1) {
- error.SetErrorToErrno();
- return error;
- }
- stdio = fcntl(terminal, F_SETFD, FD_CLOEXEC);
- if (stdio == -1) {
- error.SetErrorToErrno();
- return error;
- }
-#endif
- SetSTDIOFileDescriptor(stdio);
- }
-
- SetID(m_monitor->GetPID());
- return error;
-}
-
-void ProcessFreeBSD::DidLaunch() {}
-
-addr_t ProcessFreeBSD::GetImageInfoAddress() {
- 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;
-}
-
-Status ProcessFreeBSD::DoHalt(bool &caused_stop) {
- Status error;
-
- if (IsStopped()) {
- caused_stop = false;
- } else if (kill(GetID(), SIGSTOP)) {
- caused_stop = false;
- error.SetErrorToErrno();
- } else {
- caused_stop = true;
- }
- return error;
-}
-
-Status ProcessFreeBSD::DoSignal(int signal) {
- Status error;
-
- if (kill(GetID(), signal))
- error.SetErrorToErrno();
-
- return error;
-}
-
-Status ProcessFreeBSD::DoDestroy() {
- Status error;
-
- if (!HasExited()) {
- assert(m_monitor);
- m_exit_now = true;
- if (GetID() == LLDB_INVALID_PROCESS_ID) {
- error.SetErrorString("invalid process id");
- return error;
- }
- if (!m_monitor->Kill()) {
- error.SetErrorToErrno();
- return error;
- }
-
- SetPrivateState(eStateExited);
- }
-
- return error;
-}
-
-void ProcessFreeBSD::DoDidExec() {
- Target *target = &GetTarget();
- if (target) {
- PlatformSP platform_sp(target->GetPlatform());
- assert(platform_sp.get());
- if (platform_sp) {
- ProcessInstanceInfo process_info;
- platform_sp->GetProcessInfo(GetID(), process_info);
- ModuleSP exe_module_sp;
- ModuleSpec exe_module_spec(process_info.GetExecutableFile(),
- target->GetArchitecture());
- FileSpecList executable_search_paths(
- Target::GetDefaultExecutableSearchPaths());
- Status error = platform_sp->ResolveExecutable(
- exe_module_spec, exe_module_sp,
- executable_search_paths.GetSize() ? &executable_search_paths : NULL);
- if (!error.Success())
- return;
- target->SetExecutableModule(exe_module_sp, eLoadDependentsYes);
- }
- }
-}
-
-bool ProcessFreeBSD::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid) {
- bool added_to_set = false;
- ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid);
- if (it == m_seen_initial_stop.end()) {
- m_seen_initial_stop.insert(stop_tid);
- added_to_set = true;
- }
- return added_to_set;
-}
-
-bool ProcessFreeBSD::WaitingForInitialStop(lldb::tid_t stop_tid) {
- return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end());
-}
-
-FreeBSDThread *
-ProcessFreeBSD::CreateNewFreeBSDThread(lldb_private::Process &process,
- lldb::tid_t tid) {
- return new FreeBSDThread(process, tid);
-}
-
-void ProcessFreeBSD::RefreshStateAfterStop() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOGV(log, "message_queue size = {0}", m_message_queue.size());
-
- 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
- // breakpoint.
- while (!m_message_queue.empty()) {
- ProcessMessage &message = m_message_queue.front();
-
- // Resolve the thread this message corresponds to and pass it along.
- lldb::tid_t tid = message.GetTID();
- LLDB_LOGV(log, " message_queue size = {0}, pid = {1}",
- m_message_queue.size(), tid);
-
- m_thread_list.RefreshStateAfterStop();
-
- FreeBSDThread *thread = static_cast<FreeBSDThread *>(
- GetThreadList().FindThreadByID(tid, false).get());
- if (thread)
- thread->Notify(message);
-
- if (message.GetKind() == ProcessMessage::eExitMessage) {
- // FIXME: We should tell the user about this, but the limbo message is
- // probably better for that.
- LLDB_LOG(log, "removing thread, tid = {0}", tid);
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
-
- ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
- thread_sp.reset();
- m_seen_initial_stop.erase(tid);
- }
-
- m_message_queue.pop();
- }
-}
-
-bool ProcessFreeBSD::IsAlive() {
- StateType state = GetPrivateState();
- return state != eStateDetached && state != eStateExited &&
- state != eStateInvalid && state != eStateUnloaded;
-}
-
-size_t ProcessFreeBSD::DoReadMemory(addr_t vm_addr, void *buf, size_t size,
- Status &error) {
- assert(m_monitor);
- return m_monitor->ReadMemory(vm_addr, buf, size, error);
-}
-
-size_t ProcessFreeBSD::DoWriteMemory(addr_t vm_addr, const void *buf,
- size_t size, Status &error) {
- assert(m_monitor);
- return m_monitor->WriteMemory(vm_addr, buf, size, error);
-}
-
-addr_t ProcessFreeBSD::DoAllocateMemory(size_t size, uint32_t permissions,
- Status &error) {
- addr_t allocated_addr = LLDB_INVALID_ADDRESS;
-
- 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;
- error.Clear();
- } else {
- allocated_addr = LLDB_INVALID_ADDRESS;
- error.SetErrorStringWithFormat(
- "unable to allocate %zu bytes of memory with permissions %s", size,
- GetPermissionsAsCString(permissions));
- }
-
- return allocated_addr;
-}
-
-Status ProcessFreeBSD::DoDeallocateMemory(lldb::addr_t addr) {
- Status error;
- MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
- if (pos != m_addr_to_mmap_size.end() &&
- InferiorCallMunmap(this, addr, pos->second))
- m_addr_to_mmap_size.erase(pos);
- else
- error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64,
- addr);
-
- return error;
-}
-
-size_t
-ProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site) {
- static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xD4};
- static const uint8_t g_i386_opcode[] = {0xCC};
-
- ArchSpec arch = GetTarget().GetArchitecture();
- const uint8_t *opcode = NULL;
- size_t opcode_size = 0;
-
- switch (arch.GetMachine()) {
- default:
- assert(false && "CPU type not supported!");
- 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 = AddressClass::eUnknown;
-
- if (bp_loc_sp)
- addr_class = bp_loc_sp->GetAddress().GetAddressClass();
-
- if (addr_class == AddressClass::eCodeAlternateISA ||
- (addr_class == AddressClass::eUnknown &&
- bp_loc_sp->GetAddress().GetOffset() & 1)) {
- opcode = g_thumb_breakpoint_opcode;
- opcode_size = sizeof(g_thumb_breakpoint_opcode);
- } else {
- opcode = g_arm_breakpoint_opcode;
- opcode_size = sizeof(g_arm_breakpoint_opcode);
- }
- } break;
- case llvm::Triple::aarch64:
- opcode = g_aarch64_opcode;
- opcode_size = sizeof(g_aarch64_opcode);
- break;
-
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- opcode = g_i386_opcode;
- opcode_size = sizeof(g_i386_opcode);
- break;
- }
-
- bp_site->SetTrapOpcode(opcode, opcode_size);
- return opcode_size;
-}
-
-Status ProcessFreeBSD::EnableBreakpointSite(BreakpointSite *bp_site) {
- return EnableSoftwareBreakpoint(bp_site);
-}
-
-Status ProcessFreeBSD::DisableBreakpointSite(BreakpointSite *bp_site) {
- return DisableSoftwareBreakpoint(bp_site);
-}
-
-Status ProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify) {
- Status error;
- if (wp) {
- user_id_t watchID = wp->GetID();
- addr_t addr = wp->GetLoadAddress();
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOGF(log, "ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")",
- watchID);
- if (wp->IsEnabled()) {
- LLDB_LOGF(log,
- "ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
- watchID, (uint64_t)addr);
- return error;
- }
-
- // Try to find a vacant watchpoint slot in the inferiors' main thread
- uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
- 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)
- wp_hw_index = thread->FindVacantWatchpointIndex();
-
- if (wp_hw_index == LLDB_INVALID_INDEX32) {
- error.SetErrorString("Setting hardware watchpoint failed.");
- } else {
- wp->SetHardwareIndex(wp_hw_index);
- bool wp_enabled = true;
- uint32_t thread_count = m_thread_list.GetSize(false);
- for (uint32_t i = 0; i < thread_count; ++i) {
- thread = static_cast<FreeBSDThread *>(
- m_thread_list.GetThreadAtIndex(i, false).get());
- if (thread)
- wp_enabled &= thread->EnableHardwareWatchpoint(wp);
- else
- wp_enabled = false;
- }
- if (wp_enabled) {
- wp->SetEnabled(true, notify);
- return error;
- } else {
- // Watchpoint enabling failed on at least one of the threads so roll
- // back all of them
- DisableWatchpoint(wp, false);
- error.SetErrorString("Setting hardware watchpoint failed");
- }
- }
- } else
- error.SetErrorString("Watchpoint argument was NULL.");
- return error;
-}
-
-Status ProcessFreeBSD::DisableWatchpoint(Watchpoint *wp, bool notify) {
- Status error;
- if (wp) {
- user_id_t watchID = wp->GetID();
- addr_t addr = wp->GetLoadAddress();
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOGF(log, "ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")",
- watchID);
- if (!wp->IsEnabled()) {
- LLDB_LOGF(log,
- "ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
- watchID, (uint64_t)addr);
- // This is needed (for now) to keep watchpoints disabled correctly
- wp->SetEnabled(false, notify);
- return error;
- }
-
- if (wp->IsHardware()) {
- bool wp_disabled = true;
- 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) {
- FreeBSDThread *thread = static_cast<FreeBSDThread *>(
- m_thread_list.GetThreadAtIndex(i, false).get());
- if (thread)
- wp_disabled &= thread->DisableHardwareWatchpoint(wp);
- else
- wp_disabled = false;
- }
- if (wp_disabled) {
- wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
- wp->SetEnabled(false, notify);
- return error;
- } else
- error.SetErrorString("Disabling hardware watchpoint failed");
- }
- } else
- error.SetErrorString("Watchpoint argument was NULL.");
- return error;
-}
-
-Status ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num) {
- Status error;
- 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)
- num = thread->NumSupportedHardwareWatchpoints();
- else
- error.SetErrorString("Process does not exist.");
- return error;
-}
-
-Status ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num, bool &after) {
- Status error = GetWatchpointSupportInfo(num);
- // Watchpoints trigger and halt the inferior after the corresponding
- // instruction has been executed.
- after = true;
- return error;
-}
-
-uint32_t ProcessFreeBSD::UpdateThreadListIfNeeded() {
- std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
- // Do not allow recursive updates.
- return m_thread_list.GetSize(false);
-}
-
-ByteOrder ProcessFreeBSD::GetByteOrder() const {
- // FIXME: We should be able to extract this value directly. See comment in
- // ProcessFreeBSD().
- return m_byte_order;
-}
-
-size_t ProcessFreeBSD::PutSTDIN(const char *buf, size_t len, Status &error) {
- ssize_t status;
- if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0) {
- error.SetErrorToErrno();
- return 0;
- }
- return status;
-}
-
-// Utility functions.
-
-bool ProcessFreeBSD::HasExited() {
- switch (GetPrivateState()) {
- default:
- break;
-
- case eStateDetached:
- case eStateExited:
- return true;
- }
-
- return false;
-}
-
-bool ProcessFreeBSD::IsStopped() {
- switch (GetPrivateState()) {
- default:
- break;
-
- case eStateStopped:
- case eStateCrashed:
- case eStateSuspended:
- return true;
- }
-
- return false;
-}
-
-bool ProcessFreeBSD::IsAThreadRunning() {
- bool is_running = false;
- 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) {
- FreeBSDThread *thread = static_cast<FreeBSDThread *>(
- m_thread_list.GetThreadAtIndex(i, false).get());
- StateType thread_state = thread->GetState();
- if (thread_state == eStateRunning || thread_state == eStateStepping) {
- is_running = true;
- break;
- }
- }
- return is_running;
-}
-
-lldb_private::DataExtractor ProcessFreeBSD::GetAuxvData() {
- // If we're the local platform, we can ask the host for auxv data.
- PlatformSP platform_sp = GetTarget().GetPlatform();
- assert(platform_sp && platform_sp->IsHost());
-
- int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_AUXV, (int)m_process->GetID()};
- size_t auxv_size = AT_COUNT * sizeof(Elf_Auxinfo);
- DataBufferSP buf_sp(new DataBufferHeap(auxv_size, 0));
-
- if (::sysctl(mib, 4, buf_sp->GetBytes(), &auxv_size, NULL, 0) != 0) {
- perror("sysctl failed on auxv");
- buf_sp.reset();
- }
-
- return DataExtractor(buf_sp, GetByteOrder(), GetAddressByteSize());
-}
-
-struct EmulatorBaton {
- ProcessFreeBSD *m_process;
- RegisterContext *m_reg_context;
-
- // eRegisterKindDWARF -> RegisterValue
- std::unordered_map<uint32_t, RegisterValue> m_register_values;
-
- EmulatorBaton(ProcessFreeBSD *process, RegisterContext *reg_context)
- : m_process(process), m_reg_context(reg_context) {}
-};
-
-static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr, void *dst, size_t length) {
- EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
-
- Status error;
- size_t bytes_read =
- emulator_baton->m_process->DoReadMemory(addr, dst, length, error);
- if (!error.Success())
- bytes_read = 0;
- return bytes_read;
-}
-
-static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
- const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
-
- auto it = emulator_baton->m_register_values.find(
- reg_info->kinds[eRegisterKindDWARF]);
- if (it != emulator_baton->m_register_values.end()) {
- reg_value = it->second;
- return true;
- }
-
- // The emulator only fills in the dwarf register numbers (and in some cases
- // the generic register numbers). Get the full register info from the
- // register context based on the dwarf register numbers.
- const RegisterInfo *full_reg_info =
- emulator_baton->m_reg_context->GetRegisterInfo(
- eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]);
-
- bool error =
- emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
- return error;
-}
-
-static bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton,
- const EmulateInstruction::Context &context,
- const RegisterInfo *reg_info,
- const RegisterValue &reg_value) {
- EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
- emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] =
- reg_value;
- return true;
-}
-
-static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr, const void *dst,
- size_t length) {
- return length;
-}
-
-bool ProcessFreeBSD::SingleStepBreakpointHit(
- void *baton, lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id, lldb::user_id_t break_loc_id) {
- return false;
-}
-
-Status ProcessFreeBSD::SetSoftwareSingleStepBreakpoint(lldb::tid_t tid,
- lldb::addr_t addr) {
- Status error;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- if (log) {
- LLDB_LOGF(log, "ProcessFreeBSD::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
- LLDB_LOGF(log, "SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__,
- addr);
- }
-
- // Validate the address.
- if (addr == LLDB_INVALID_ADDRESS)
- return Status("ProcessFreeBSD::%s invalid load address specified.",
- __FUNCTION__);
-
- Breakpoint *const sw_step_break =
- m_process->GetTarget().CreateBreakpoint(addr, true, false).get();
- sw_step_break->SetCallback(SingleStepBreakpointHit, this, true);
- sw_step_break->SetBreakpointKind("software-single-step");
-
- LLDB_LOGF(log, "ProcessFreeBSD::%s addr = 0x%" PRIx64 " -- SUCCESS",
- __FUNCTION__, addr);
-
- m_threads_stepping_with_breakpoint.insert({tid, sw_step_break->GetID()});
- return Status();
-}
-
-bool ProcessFreeBSD::IsSoftwareStepBreakpoint(lldb::tid_t tid) {
- ThreadSP thread = GetThreadList().FindThreadByID(tid);
- if (!thread)
- return false;
-
- assert(thread->GetRegisterContext());
- lldb::addr_t stop_pc = thread->GetRegisterContext()->GetPC();
-
- const auto &iter = m_threads_stepping_with_breakpoint.find(tid);
- if (iter == m_threads_stepping_with_breakpoint.end())
- return false;
-
- lldb::break_id_t bp_id = iter->second;
- BreakpointSP bp = GetTarget().GetBreakpointByID(bp_id);
- if (!bp)
- return false;
-
- BreakpointLocationSP bp_loc = bp->FindLocationByAddress(stop_pc);
- if (!bp_loc)
- return false;
-
- GetTarget().RemoveBreakpointByID(bp_id);
- m_threads_stepping_with_breakpoint.erase(tid);
- return true;
-}
-
-bool ProcessFreeBSD::SupportHardwareSingleStepping() const {
- lldb_private::ArchSpec arch = GetTarget().GetArchitecture();
- if (arch.GetMachine() == llvm::Triple::arm || arch.IsMIPS())
- return false;
- return true;
-}
-
-Status ProcessFreeBSD::SetupSoftwareSingleStepping(lldb::tid_t tid) {
- std::unique_ptr<EmulateInstruction> emulator_up(
- EmulateInstruction::FindPlugin(GetTarget().GetArchitecture(),
- eInstructionTypePCModifying, nullptr));
-
- if (emulator_up == nullptr)
- return Status("Instruction emulator not found!");
-
- FreeBSDThread *thread = static_cast<FreeBSDThread *>(
- m_thread_list.FindThreadByID(tid, false).get());
- if (thread == NULL)
- return Status("Thread not found not found!");
-
- lldb::RegisterContextSP register_context_sp = thread->GetRegisterContext();
-
- EmulatorBaton baton(this, register_context_sp.get());
- emulator_up->SetBaton(&baton);
- emulator_up->SetReadMemCallback(&ReadMemoryCallback);
- emulator_up->SetReadRegCallback(&ReadRegisterCallback);
- emulator_up->SetWriteMemCallback(&WriteMemoryCallback);
- emulator_up->SetWriteRegCallback(&WriteRegisterCallback);
-
- if (!emulator_up->ReadInstruction())
- return Status("Read instruction failed!");
-
- bool emulation_result =
- emulator_up->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
- const RegisterInfo *reg_info_pc = register_context_sp->GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- auto pc_it =
- baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]);
-
- lldb::addr_t next_pc;
- if (emulation_result) {
- assert(pc_it != baton.m_register_values.end() &&
- "Emulation was successful but PC wasn't updated");
- next_pc = pc_it->second.GetAsUInt64();
- } else if (pc_it == baton.m_register_values.end()) {
- // Emulate instruction failed and it haven't changed PC. Advance PC with
- // the size of the current opcode because the emulation of all
- // PC modifying instruction should be successful. The failure most
- // likely caused by a not supported instruction which don't modify PC.
- next_pc =
- register_context_sp->GetPC() + emulator_up->GetOpcode().GetByteSize();
- } else {
- // The instruction emulation failed after it modified the PC. It is an
- // unknown error where we can't continue because the next instruction is
- // modifying the PC but we don't know how.
- return Status("Instruction emulation failed unexpectedly");
- }
-
- SetSoftwareSingleStepBreakpoint(tid, next_pc);
- return Status();
-}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
deleted file mode 100644
index 536da0c0aa70..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
+++ /dev/null
@@ -1,220 +0,0 @@
-//===-- ProcessFreeBSD.h ------------------------------------------*- C++
-//-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ProcessFreeBSD_H_
-#define liblldb_ProcessFreeBSD_H_
-
-#include "Plugins/Process/POSIX/ProcessMessage.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/ThreadList.h"
-#include <mutex>
-#include <queue>
-#include <set>
-
-class ProcessMonitor;
-class FreeBSDThread;
-
-class ProcessFreeBSD : public lldb_private::Process {
-
-public:
- // Static functions.
- static lldb::ProcessSP
- CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec *crash_file_path);
-
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetPluginDescriptionStatic();
-
- // Constructors and destructors
- ProcessFreeBSD(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
- lldb::UnixSignalsSP &unix_signals_sp);
-
- ~ProcessFreeBSD();
-
- virtual lldb_private::Status WillResume() override;
-
- // PluginInterface protocol
- virtual lldb_private::ConstString GetPluginName() override;
-
- virtual uint32_t GetPluginVersion() override;
-
-public:
- // Process protocol.
- void Finalize() override;
-
- bool CanDebug(lldb::TargetSP target_sp,
- bool plugin_specified_by_name) override;
-
- lldb_private::Status WillLaunch(lldb_private::Module *module) override;
-
- lldb_private::Status DoAttachToProcessWithID(
- lldb::pid_t pid,
- const lldb_private::ProcessAttachInfo &attach_info) override;
-
- lldb_private::Status
- DoLaunch(lldb_private::Module *exe_module,
- lldb_private::ProcessLaunchInfo &launch_info) override;
-
- void DidLaunch() override;
-
- lldb_private::Status DoResume() override;
-
- lldb_private::Status DoHalt(bool &caused_stop) override;
-
- lldb_private::Status DoDetach(bool keep_stopped) override;
-
- lldb_private::Status DoSignal(int signal) override;
-
- lldb_private::Status DoDestroy() override;
-
- void DoDidExec() override;
-
- void RefreshStateAfterStop() override;
-
- bool IsAlive() override;
-
- size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
- lldb_private::Status &error) override;
-
- size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
- lldb_private::Status &error) override;
-
- lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
- lldb_private::Status &error) override;
-
- lldb_private::Status DoDeallocateMemory(lldb::addr_t ptr) override;
-
- virtual size_t
- GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite *bp_site);
-
- lldb_private::Status
- EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
-
- lldb_private::Status
- DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
-
- lldb_private::Status EnableWatchpoint(lldb_private::Watchpoint *wp,
- bool notify = true) override;
-
- lldb_private::Status DisableWatchpoint(lldb_private::Watchpoint *wp,
- bool notify = true) override;
-
- lldb_private::Status GetWatchpointSupportInfo(uint32_t &num) override;
-
- lldb_private::Status GetWatchpointSupportInfo(uint32_t &num,
- bool &after) override;
-
- virtual uint32_t UpdateThreadListIfNeeded();
-
- bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
- lldb_private::ThreadList &new_thread_list) override;
-
- virtual lldb::ByteOrder GetByteOrder() const;
-
- lldb::addr_t GetImageInfoAddress() override;
-
- size_t PutSTDIN(const char *buf, size_t len,
- lldb_private::Status &error) override;
-
- lldb_private::DataExtractor GetAuxvData() override;
-
- // ProcessFreeBSD internal API.
-
- /// Registers the given message with this process.
- virtual void SendMessage(const ProcessMessage &message);
-
- ProcessMonitor &GetMonitor() {
- assert(m_monitor);
- return *m_monitor;
- }
-
- lldb_private::FileSpec
- GetFileSpec(const lldb_private::FileAction *file_action,
- const lldb_private::FileSpec &default_file_spec,
- const lldb_private::FileSpec &dbg_pts_file_spec);
-
- /// Adds the thread to the list of threads for which we have received the
- /// initial stopping signal.
- /// The \p stop_tid parameter indicates the thread which the stop happened
- /// for.
- bool AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid);
-
- bool WaitingForInitialStop(lldb::tid_t stop_tid);
-
- virtual FreeBSDThread *CreateNewFreeBSDThread(lldb_private::Process &process,
- lldb::tid_t tid);
-
- static bool SingleStepBreakpointHit(
- void *baton, lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
-
- lldb_private::Status SetupSoftwareSingleStepping(lldb::tid_t tid);
-
- lldb_private::Status SetSoftwareSingleStepBreakpoint(lldb::tid_t tid,
- lldb::addr_t addr);
-
- bool IsSoftwareStepBreakpoint(lldb::tid_t tid);
-
- bool SupportHardwareSingleStepping() const;
-
- typedef std::vector<lldb::tid_t> tid_collection;
- tid_collection &GetStepTids() { return m_step_tids; }
-
-protected:
- static const size_t MAX_TRAP_OPCODE_SIZE = 8;
-
- /// Target byte order.
- lldb::ByteOrder m_byte_order;
-
- /// Process monitor;
- ProcessMonitor *m_monitor;
-
- /// The module we are executing.
- lldb_private::Module *m_module;
-
- /// Message queue notifying this instance of inferior process state changes.
- std::recursive_mutex m_message_mutex;
- std::queue<ProcessMessage> m_message_queue;
-
- /// Drive any exit events to completion.
- bool m_exit_now;
-
- /// Returns true if the process has exited.
- bool HasExited();
-
- /// Returns true if the process is stopped.
- bool IsStopped();
-
- /// Returns true if at least one running is currently running
- bool IsAThreadRunning();
-
- typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
- MMapMap m_addr_to_mmap_size;
-
- typedef std::set<lldb::tid_t> ThreadStopSet;
- /// Every thread begins with a stop signal. This keeps track
- /// of the threads for which we have received the stop signal.
- ThreadStopSet m_seen_initial_stop;
-
- friend class FreeBSDThread;
-
- tid_collection m_suspend_tids;
- tid_collection m_run_tids;
- tid_collection m_step_tids;
- std::map<lldb::tid_t, lldb::break_id_t> m_threads_stepping_with_breakpoint;
-
- int m_resume_signo;
-};
-
-#endif // liblldb_ProcessFreeBSD_H_
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
deleted file mode 100644
index 050cab730d67..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ /dev/null
@@ -1,1427 +0,0 @@
-//===-- ProcessMonitor.cpp ------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include <errno.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/ptrace.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "lldb/Host/Host.h"
-#include "lldb/Host/PseudoTerminal.h"
-#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Target/UnixSignals.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Scalar.h"
-#include "lldb/Utility/Status.h"
-#include "llvm/Support/Errno.h"
-
-#include "FreeBSDThread.h"
-#include "Plugins/Process/POSIX/CrashReason.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "ProcessFreeBSD.h"
-#include "ProcessMonitor.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-// Wrapper for ptrace to catch errors and log calls.
-
-const char *Get_PT_IO_OP(int op) {
- switch (op) {
- case PIOD_READ_D:
- return "READ_D";
- case PIOD_WRITE_D:
- return "WRITE_D";
- case PIOD_READ_I:
- return "READ_I";
- case PIOD_WRITE_I:
- return "WRITE_I";
- default:
- return "Unknown op";
- }
-}
-
-// Wrapper for ptrace to catch errors and log calls. Note that ptrace sets
-// errno on error because -1 is reserved as a valid result.
-extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
- const char *reqName, const char *file, int line) {
- long int result;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
- if (log) {
- LLDB_LOGF(log,
- "ptrace(%s, %" PRIu64 ", %p, %x) called from file %s line %d",
- reqName, pid, addr, data, file, line);
- if (req == PT_IO) {
- struct ptrace_io_desc *pi = (struct ptrace_io_desc *)addr;
-
- LLDB_LOGF(log, "PT_IO: op=%s offs=%zx size=%zu",
- Get_PT_IO_OP(pi->piod_op), (size_t)pi->piod_offs, pi->piod_len);
- }
- }
-
- // PtraceDisplayBytes(req, data);
-
- errno = 0;
- result = ptrace(req, pid, (caddr_t)addr, data);
-
- // PtraceDisplayBytes(req, data);
-
- if (log && errno != 0) {
- const char *str;
- switch (errno) {
- case ESRCH:
- str = "ESRCH";
- break;
- case EINVAL:
- str = "EINVAL";
- break;
- case EBUSY:
- str = "EBUSY";
- break;
- case EPERM:
- str = "EPERM";
- break;
- default:
- str = "<unknown>";
- }
- LLDB_LOGF(log, "ptrace() failed; errno=%d (%s)", errno, str);
- }
-
- if (log) {
-#ifdef __amd64__
- if (req == PT_GETREGS) {
- struct reg *r = (struct reg *)addr;
-
- LLDB_LOGF(log, "PT_GETREGS: rip=0x%lx rsp=0x%lx rbp=0x%lx rax=0x%lx",
- r->r_rip, r->r_rsp, r->r_rbp, r->r_rax);
- }
- if (req == PT_GETDBREGS || req == PT_SETDBREGS) {
- struct dbreg *r = (struct dbreg *)addr;
- char setget = (req == PT_GETDBREGS) ? 'G' : 'S';
-
- for (int i = 0; i <= 7; i++)
- LLDB_LOGF(log, "PT_%cETDBREGS: dr[%d]=0x%lx", setget, i, r->dr[i]);
- }
-#endif
- }
-
- return result;
-}
-
-// Wrapper for ptrace when logging is not required. Sets errno to 0 prior to
-// calling ptrace.
-extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data) {
- long result = 0;
- errno = 0;
- result = ptrace(req, pid, (caddr_t)addr, data);
- return result;
-}
-
-#define PTRACE(req, pid, addr, data) \
- PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__)
-
-// Static implementations of ProcessMonitor::ReadMemory and
-// ProcessMonitor::WriteMemory. This enables mutual recursion between these
-// functions without needed to go thru the thread funnel.
-
-static size_t DoReadMemory(lldb::pid_t pid, lldb::addr_t vm_addr, void *buf,
- size_t size, Status &error) {
- struct ptrace_io_desc pi_desc;
-
- pi_desc.piod_op = PIOD_READ_D;
- pi_desc.piod_offs = (void *)vm_addr;
- pi_desc.piod_addr = buf;
- pi_desc.piod_len = size;
-
- if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0) {
- error.SetErrorToErrno();
- return 0;
- }
- return pi_desc.piod_len;
-}
-
-static size_t DoWriteMemory(lldb::pid_t pid, lldb::addr_t vm_addr,
- const void *buf, size_t size, Status &error) {
- struct ptrace_io_desc pi_desc;
-
- pi_desc.piod_op = PIOD_WRITE_D;
- pi_desc.piod_offs = (void *)vm_addr;
- pi_desc.piod_addr = const_cast<void *>(buf);
- pi_desc.piod_len = size;
-
- if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0) {
- error.SetErrorToErrno();
- return 0;
- }
- return pi_desc.piod_len;
-}
-
-// Simple helper function to ensure flags are enabled on the given file
-// descriptor.
-static bool EnsureFDFlags(int fd, int flags, Status &error) {
- int status;
-
- if ((status = fcntl(fd, F_GETFL)) == -1) {
- error.SetErrorToErrno();
- return false;
- }
-
- if (fcntl(fd, F_SETFL, status | flags) == -1) {
- error.SetErrorToErrno();
- return false;
- }
-
- return true;
-}
-
-/// \class Operation
-/// Represents a ProcessMonitor operation.
-///
-/// Under FreeBSD, it is not possible to ptrace() from any other thread but
-/// the one that spawned or attached to the process from the start.
-/// Therefore, when a ProcessMonitor is asked to deliver or change the state
-/// of an inferior process the operation must be "funneled" to a specific
-/// thread to perform the task. The Operation class provides an abstract base
-/// for all services the ProcessMonitor must perform via the single virtual
-/// function Execute, thus encapsulating the code that needs to run in the
-/// privileged context.
-class Operation {
-public:
- virtual ~Operation() {}
- virtual void Execute(ProcessMonitor *monitor) = 0;
-};
-
-/// \class ReadOperation
-/// Implements ProcessMonitor::ReadMemory.
-class ReadOperation : public Operation {
-public:
- ReadOperation(lldb::addr_t addr, void *buff, size_t size, Status &error,
- size_t &result)
- : m_addr(addr), m_buff(buff), m_size(size), m_error(error),
- m_result(result) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- lldb::addr_t m_addr;
- void *m_buff;
- size_t m_size;
- Status &m_error;
- size_t &m_result;
-};
-
-void ReadOperation::Execute(ProcessMonitor *monitor) {
- lldb::pid_t pid = monitor->GetPID();
-
- m_result = DoReadMemory(pid, m_addr, m_buff, m_size, m_error);
-}
-
-/// \class WriteOperation
-/// Implements ProcessMonitor::WriteMemory.
-class WriteOperation : public Operation {
-public:
- WriteOperation(lldb::addr_t addr, const void *buff, size_t size,
- Status &error, size_t &result)
- : m_addr(addr), m_buff(buff), m_size(size), m_error(error),
- m_result(result) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- lldb::addr_t m_addr;
- const void *m_buff;
- size_t m_size;
- Status &m_error;
- size_t &m_result;
-};
-
-void WriteOperation::Execute(ProcessMonitor *monitor) {
- lldb::pid_t pid = monitor->GetPID();
-
- m_result = DoWriteMemory(pid, m_addr, m_buff, m_size, m_error);
-}
-
-/// \class ReadRegOperation
-/// Implements ProcessMonitor::ReadRegisterValue.
-class ReadRegOperation : public Operation {
-public:
- ReadRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
- RegisterValue &value, bool &result)
- : m_tid(tid), m_offset(offset), m_size(size), m_value(value),
- m_result(result) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- lldb::tid_t m_tid;
- unsigned m_offset;
- unsigned m_size;
- RegisterValue &m_value;
- bool &m_result;
-};
-
-void ReadRegOperation::Execute(ProcessMonitor *monitor) {
- struct reg regs;
- int rc;
-
- if ((rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)&regs, 0)) < 0) {
- m_result = false;
- } else {
- // 'struct reg' contains only 32- or 64-bit register values. Punt on
- // others. Also, not all entries may be uintptr_t sized, such as 32-bit
- // processes on powerpc64 (probably the same for i386 on amd64)
- if (m_size == sizeof(uint32_t))
- m_value = *(uint32_t *)(((caddr_t)&regs) + m_offset);
- else if (m_size == sizeof(uint64_t))
- m_value = *(uint64_t *)(((caddr_t)&regs) + m_offset);
- else
- memcpy((void *)&m_value, (((caddr_t)&regs) + m_offset), m_size);
- m_result = true;
- }
-}
-
-/// \class WriteRegOperation
-/// Implements ProcessMonitor::WriteRegisterValue.
-class WriteRegOperation : public Operation {
-public:
- WriteRegOperation(lldb::tid_t tid, unsigned offset,
- const RegisterValue &value, bool &result)
- : m_tid(tid), m_offset(offset), m_value(value), m_result(result) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- lldb::tid_t m_tid;
- unsigned m_offset;
- const RegisterValue &m_value;
- bool &m_result;
-};
-
-void WriteRegOperation::Execute(ProcessMonitor *monitor) {
- struct reg regs;
-
- if (PTRACE(PT_GETREGS, m_tid, (caddr_t)&regs, 0) < 0) {
- m_result = false;
- return;
- }
- *(uintptr_t *)(((caddr_t)&regs) + m_offset) =
- (uintptr_t)m_value.GetAsUInt64();
- if (PTRACE(PT_SETREGS, m_tid, (caddr_t)&regs, 0) < 0)
- m_result = false;
- else
- m_result = true;
-}
-
-/// \class ReadDebugRegOperation
-/// Implements ProcessMonitor::ReadDebugRegisterValue.
-class ReadDebugRegOperation : public Operation {
-public:
- ReadDebugRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
- RegisterValue &value, bool &result)
- : m_tid(tid), m_offset(offset), m_size(size), m_value(value),
- m_result(result) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- lldb::tid_t m_tid;
- unsigned m_offset;
- unsigned m_size;
- RegisterValue &m_value;
- bool &m_result;
-};
-
-void ReadDebugRegOperation::Execute(ProcessMonitor *monitor) {
- struct dbreg regs;
- int rc;
-
- if ((rc = PTRACE(PT_GETDBREGS, m_tid, (caddr_t)&regs, 0)) < 0) {
- m_result = false;
- } else {
- if (m_size == sizeof(uintptr_t))
- m_value = *(uintptr_t *)(((caddr_t)&regs) + m_offset);
- else
- memcpy((void *)&m_value, (((caddr_t)&regs) + m_offset), m_size);
- m_result = true;
- }
-}
-
-/// \class WriteDebugRegOperation
-/// Implements ProcessMonitor::WriteDebugRegisterValue.
-class WriteDebugRegOperation : public Operation {
-public:
- WriteDebugRegOperation(lldb::tid_t tid, unsigned offset,
- const RegisterValue &value, bool &result)
- : m_tid(tid), m_offset(offset), m_value(value), m_result(result) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- lldb::tid_t m_tid;
- unsigned m_offset;
- const RegisterValue &m_value;
- bool &m_result;
-};
-
-void WriteDebugRegOperation::Execute(ProcessMonitor *monitor) {
- struct dbreg regs;
-
- if (PTRACE(PT_GETDBREGS, m_tid, (caddr_t)&regs, 0) < 0) {
- m_result = false;
- return;
- }
- *(uintptr_t *)(((caddr_t)&regs) + m_offset) =
- (uintptr_t)m_value.GetAsUInt64();
- if (PTRACE(PT_SETDBREGS, m_tid, (caddr_t)&regs, 0) < 0)
- m_result = false;
- else
- m_result = true;
-}
-
-/// \class ReadGPROperation
-/// Implements ProcessMonitor::ReadGPR.
-class ReadGPROperation : public Operation {
-public:
- ReadGPROperation(lldb::tid_t tid, void *buf, bool &result)
- : m_tid(tid), m_buf(buf), m_result(result) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- lldb::tid_t m_tid;
- void *m_buf;
- bool &m_result;
-};
-
-void ReadGPROperation::Execute(ProcessMonitor *monitor) {
- int rc;
-
- errno = 0;
- rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)m_buf, 0);
- if (errno != 0)
- m_result = false;
- else
- m_result = true;
-}
-
-/// \class ReadFPROperation
-/// Implements ProcessMonitor::ReadFPR.
-class ReadFPROperation : public Operation {
-public:
- ReadFPROperation(lldb::tid_t tid, void *buf, bool &result)
- : m_tid(tid), m_buf(buf), m_result(result) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- lldb::tid_t m_tid;
- void *m_buf;
- bool &m_result;
-};
-
-void ReadFPROperation::Execute(ProcessMonitor *monitor) {
- if (PTRACE(PT_GETFPREGS, m_tid, (caddr_t)m_buf, 0) < 0)
- m_result = false;
- else
- m_result = true;
-}
-
-/// \class WriteGPROperation
-/// Implements ProcessMonitor::WriteGPR.
-class WriteGPROperation : public Operation {
-public:
- WriteGPROperation(lldb::tid_t tid, void *buf, bool &result)
- : m_tid(tid), m_buf(buf), m_result(result) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- lldb::tid_t m_tid;
- void *m_buf;
- bool &m_result;
-};
-
-void WriteGPROperation::Execute(ProcessMonitor *monitor) {
- if (PTRACE(PT_SETREGS, m_tid, (caddr_t)m_buf, 0) < 0)
- m_result = false;
- else
- m_result = true;
-}
-
-/// \class WriteFPROperation
-/// Implements ProcessMonitor::WriteFPR.
-class WriteFPROperation : public Operation {
-public:
- WriteFPROperation(lldb::tid_t tid, void *buf, bool &result)
- : m_tid(tid), m_buf(buf), m_result(result) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- lldb::tid_t m_tid;
- void *m_buf;
- bool &m_result;
-};
-
-void WriteFPROperation::Execute(ProcessMonitor *monitor) {
- if (PTRACE(PT_SETFPREGS, m_tid, (caddr_t)m_buf, 0) < 0)
- m_result = false;
- else
- m_result = true;
-}
-
-/// \class ResumeOperation
-/// Implements ProcessMonitor::Resume.
-class ResumeOperation : public Operation {
-public:
- ResumeOperation(uint32_t signo, bool &result)
- : m_signo(signo), m_result(result) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- uint32_t m_signo;
- bool &m_result;
-};
-
-void ResumeOperation::Execute(ProcessMonitor *monitor) {
- lldb::pid_t pid = monitor->GetPID();
- int data = 0;
-
- if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
- data = m_signo;
-
- if (PTRACE(PT_CONTINUE, pid, (caddr_t)1, data)) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log, "ResumeOperation ({0}) failed: {1}", pid,
- llvm::sys::StrError(errno));
- m_result = false;
- } else
- m_result = true;
-}
-
-/// \class SingleStepOperation
-/// Implements ProcessMonitor::SingleStep.
-class SingleStepOperation : public Operation {
-public:
- SingleStepOperation(uint32_t signo, bool &result)
- : m_signo(signo), m_result(result) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- uint32_t m_signo;
- bool &m_result;
-};
-
-void SingleStepOperation::Execute(ProcessMonitor *monitor) {
- lldb::pid_t pid = monitor->GetPID();
- int data = 0;
-
- if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
- data = m_signo;
-
- if (PTRACE(PT_STEP, pid, NULL, data))
- m_result = false;
- else
- m_result = true;
-}
-
-/// \class LwpInfoOperation
-/// Implements ProcessMonitor::GetLwpInfo.
-class LwpInfoOperation : public Operation {
-public:
- LwpInfoOperation(lldb::tid_t tid, void *info, bool &result, int &ptrace_err)
- : m_tid(tid), m_info(info), m_result(result), m_err(ptrace_err) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- lldb::tid_t m_tid;
- void *m_info;
- bool &m_result;
- int &m_err;
-};
-
-void LwpInfoOperation::Execute(ProcessMonitor *monitor) {
- struct ptrace_lwpinfo plwp;
-
- if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp))) {
- m_result = false;
- m_err = errno;
- } else {
- memcpy(m_info, &plwp, sizeof(plwp));
- m_result = true;
- }
-}
-
-/// \class ThreadSuspendOperation
-/// Implements ProcessMonitor::ThreadSuspend.
-class ThreadSuspendOperation : public Operation {
-public:
- ThreadSuspendOperation(lldb::tid_t tid, bool suspend, bool &result)
- : m_tid(tid), m_suspend(suspend), m_result(result) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- lldb::tid_t m_tid;
- bool m_suspend;
- bool &m_result;
-};
-
-void ThreadSuspendOperation::Execute(ProcessMonitor *monitor) {
- m_result = !PTRACE(m_suspend ? PT_SUSPEND : PT_RESUME, m_tid, NULL, 0);
-}
-
-/// \class EventMessageOperation
-/// Implements ProcessMonitor::GetEventMessage.
-class EventMessageOperation : public Operation {
-public:
- EventMessageOperation(lldb::tid_t tid, unsigned long *message, bool &result)
- : m_tid(tid), m_message(message), m_result(result) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- lldb::tid_t m_tid;
- unsigned long *m_message;
- bool &m_result;
-};
-
-void EventMessageOperation::Execute(ProcessMonitor *monitor) {
- struct ptrace_lwpinfo plwp;
-
- if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp)))
- m_result = false;
- else {
- if (plwp.pl_flags & PL_FLAG_FORKED) {
- *m_message = plwp.pl_child_pid;
- m_result = true;
- } else
- m_result = false;
- }
-}
-
-/// \class KillOperation
-/// Implements ProcessMonitor::Kill.
-class KillOperation : public Operation {
-public:
- KillOperation(bool &result) : m_result(result) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- bool &m_result;
-};
-
-void KillOperation::Execute(ProcessMonitor *monitor) {
- lldb::pid_t pid = monitor->GetPID();
-
- if (PTRACE(PT_KILL, pid, NULL, 0))
- m_result = false;
- else
- m_result = true;
-}
-
-/// \class DetachOperation
-/// Implements ProcessMonitor::Detach.
-class DetachOperation : public Operation {
-public:
- DetachOperation(Status &result) : m_error(result) {}
-
- void Execute(ProcessMonitor *monitor);
-
-private:
- Status &m_error;
-};
-
-void DetachOperation::Execute(ProcessMonitor *monitor) {
- lldb::pid_t pid = monitor->GetPID();
-
- if (PTRACE(PT_DETACH, pid, NULL, 0) < 0)
- m_error.SetErrorToErrno();
-}
-
-ProcessMonitor::OperationArgs::OperationArgs(ProcessMonitor *monitor)
- : m_monitor(monitor) {
- sem_init(&m_semaphore, 0, 0);
-}
-
-ProcessMonitor::OperationArgs::~OperationArgs() { sem_destroy(&m_semaphore); }
-
-ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor,
- lldb_private::Module *module,
- char const **argv, Environment env,
- const FileSpec &stdin_file_spec,
- const FileSpec &stdout_file_spec,
- const FileSpec &stderr_file_spec,
- const FileSpec &working_dir)
- : OperationArgs(monitor), m_module(module), m_argv(argv),
- m_env(std::move(env)), 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) {}
-
-ProcessMonitor::LaunchArgs::~LaunchArgs() {}
-
-ProcessMonitor::AttachArgs::AttachArgs(ProcessMonitor *monitor, lldb::pid_t pid)
- : OperationArgs(monitor), m_pid(pid) {}
-
-ProcessMonitor::AttachArgs::~AttachArgs() {}
-
-/// The basic design of the ProcessMonitor is built around two threads.
-///
-/// One thread (@see SignalThread) simply blocks on a call to waitpid()
-/// looking for changes in the debugee state. When a change is detected a
-/// ProcessMessage is sent to the associated ProcessFreeBSD instance. This
-/// thread "drives" state changes in the debugger.
-///
-/// The second thread (@see OperationThread) is responsible for two things 1)
-/// launching or attaching to the inferior process, and then 2) servicing
-/// operations such as register reads/writes, stepping, etc. See the comments
-/// on the Operation class for more info as to why this is needed.
-ProcessMonitor::ProcessMonitor(
- ProcessFreeBSD *process, Module *module, const char *argv[],
- Environment env, const FileSpec &stdin_file_spec,
- const FileSpec &stdout_file_spec, const FileSpec &stderr_file_spec,
- const FileSpec &working_dir,
- const lldb_private::ProcessLaunchInfo & /* launch_info */,
- lldb_private::Status &error)
- : m_process(static_cast<ProcessFreeBSD *>(process)),
- m_operation_thread(), m_monitor_thread(), m_pid(LLDB_INVALID_PROCESS_ID), m_terminal_fd(-1), m_operation(0) {
- using namespace std::placeholders;
-
- std::unique_ptr<LaunchArgs> args(
- new LaunchArgs(this, module, argv, std::move(env), stdin_file_spec,
- stdout_file_spec, stderr_file_spec, working_dir));
-
- sem_init(&m_operation_pending, 0, 0);
- sem_init(&m_operation_done, 0, 0);
-
- StartLaunchOpThread(args.get(), error);
- if (!error.Success())
- return;
-
- if (llvm::sys::RetryAfterSignal(-1, sem_wait, &args->m_semaphore) == -1) {
- error.SetErrorToErrno();
- return;
- }
-
- // Check that the launch was a success.
- if (!args->m_error.Success()) {
- StopOpThread();
- error = args->m_error;
- return;
- }
-
- // Finally, start monitoring the child process for change in state.
- llvm::Expected<lldb_private::HostThread> monitor_thread =
- Host::StartMonitoringChildProcess(
- std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4),
- GetPID(), true);
- if (!monitor_thread || !monitor_thread->IsJoinable()) {
- error.SetErrorToGenericError();
- error.SetErrorString("Process launch failed.");
- return;
- }
- m_monitor_thread = *monitor_thread;
-}
-
-ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process, lldb::pid_t pid,
- lldb_private::Status &error)
- : m_process(static_cast<ProcessFreeBSD *>(process)),
- m_operation_thread(), m_monitor_thread(), m_pid(pid), 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);
-
- std::unique_ptr<AttachArgs> args(new AttachArgs(this, pid));
-
- StartAttachOpThread(args.get(), error);
- if (!error.Success())
- return;
-
- if (llvm::sys::RetryAfterSignal(-1, sem_wait, &args->m_semaphore) == -1) {
- error.SetErrorToErrno();
- return;
- }
-
- // Check that the attach was a success.
- if (!args->m_error.Success()) {
- StopOpThread();
- error = args->m_error;
- return;
- }
-
- // Finally, start monitoring the child process for change in state.
- llvm::Expected<lldb_private::HostThread> monitor_thread =
- Host::StartMonitoringChildProcess(
- std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4),
- GetPID(), true);
- if (!monitor_thread || !monitor_thread->IsJoinable()) {
- error.SetErrorToGenericError();
- error.SetErrorString("Process attach failed.");
- return;
- }
- m_monitor_thread = *monitor_thread;
-}
-
-ProcessMonitor::~ProcessMonitor() { StopMonitor(); }
-
-// Thread setup and tear down.
-void ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Status &error) {
- static const char *g_thread_name = "freebsd.op";
-
- if (m_operation_thread && m_operation_thread->IsJoinable())
- return;
-
- llvm::Expected<lldb_private::HostThread> operation_thread =
- ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args);
- if (operation_thread)
- m_operation_thread = *operation_thread;
- else
- error = operation_thread.takeError();
-}
-
-void *ProcessMonitor::LaunchOpThread(void *arg) {
- LaunchArgs *args = static_cast<LaunchArgs *>(arg);
-
- if (!Launch(args)) {
- sem_post(&args->m_semaphore);
- return NULL;
- }
-
- ServeOperation(args);
- return NULL;
-}
-
-bool ProcessMonitor::Launch(LaunchArgs *args) {
- ProcessMonitor *monitor = args->m_monitor;
- ProcessFreeBSD &process = monitor->GetProcess();
- const char **argv = args->m_argv;
- const FileSpec &stdin_file_spec = args->m_stdin_file_spec;
- const FileSpec &stdout_file_spec = args->m_stdout_file_spec;
- const FileSpec &stderr_file_spec = args->m_stderr_file_spec;
- const FileSpec &working_dir = args->m_working_dir;
-
- PseudoTerminal terminal;
- const size_t err_len = 1024;
- char err_str[err_len];
- ::pid_t pid;
-
- // Propagate the environment if one is not supplied.
- Environment::Envp envp =
- (args->m_env.empty() ? Host::GetEnvironment() : args->m_env).getEnvp();
-
- if ((pid = terminal.Fork(err_str, err_len)) == -1) {
- args->m_error.SetErrorToGenericError();
- args->m_error.SetErrorString("Process fork failed.");
- goto FINISH;
- }
-
- // Recognized child exit status codes.
- enum {
- ePtraceFailed = 1,
- eDupStdinFailed,
- eDupStdoutFailed,
- eDupStderrFailed,
- eChdirFailed,
- eExecFailed,
- eSetGidFailed
- };
-
- // Child process.
- if (pid == 0) {
- // Trace this process.
- if (PTRACE(PT_TRACE_ME, 0, NULL, 0) < 0)
- 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.CloseSecondaryFileDescriptor();
-
- // Do not inherit setgid powers.
- if (setgid(getgid()) != 0)
- exit(eSetGidFailed);
-
- // Let us have our own process group.
- setpgid(0, 0);
-
- // Dup file descriptors if needed.
- //
- // FIXME: If two or more of the paths are the same we needlessly open
- // the same file multiple times.
- if (stdin_file_spec)
- if (!DupDescriptor(stdin_file_spec, STDIN_FILENO, O_RDONLY))
- exit(eDupStdinFailed);
-
- if (stdout_file_spec)
- if (!DupDescriptor(stdout_file_spec, STDOUT_FILENO, O_WRONLY | O_CREAT))
- exit(eDupStdoutFailed);
-
- if (stderr_file_spec)
- if (!DupDescriptor(stderr_file_spec, STDERR_FILENO, O_WRONLY | O_CREAT))
- exit(eDupStderrFailed);
-
- // Change working directory
- if (working_dir && 0 != ::chdir(working_dir.GetCString()))
- exit(eChdirFailed);
-
- // Execute. We should never return.
- execve(argv[0], const_cast<char *const *>(argv), envp);
- exit(eExecFailed);
- }
-
- // Wait for the child process to to trap on its call to execve.
- ::pid_t wpid;
- int status;
- if ((wpid = waitpid(pid, &status, 0)) < 0) {
- args->m_error.SetErrorToErrno();
- goto FINISH;
- } else if (WIFEXITED(status)) {
- // open, dup or execve likely failed for some reason.
- args->m_error.SetErrorToGenericError();
- switch (WEXITSTATUS(status)) {
- case ePtraceFailed:
- args->m_error.SetErrorString("Child ptrace failed.");
- break;
- case eDupStdinFailed:
- args->m_error.SetErrorString("Child open stdin failed.");
- break;
- case eDupStdoutFailed:
- args->m_error.SetErrorString("Child open stdout failed.");
- break;
- case eDupStderrFailed:
- args->m_error.SetErrorString("Child open stderr failed.");
- break;
- case eChdirFailed:
- args->m_error.SetErrorString("Child failed to set working directory.");
- break;
- case eExecFailed:
- args->m_error.SetErrorString("Child exec failed.");
- break;
- case eSetGidFailed:
- args->m_error.SetErrorString("Child setgid failed.");
- break;
- default:
- args->m_error.SetErrorString("Child returned unknown exit status.");
- break;
- }
- goto FINISH;
- }
- assert(WIFSTOPPED(status) && wpid == (::pid_t)pid &&
- "Could not sync with inferior process.");
-
-#ifdef notyet
- // Have the child raise an event on exit. This is used to keep the child in
- // limbo until it is destroyed.
- if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_TRACEEXIT) < 0) {
- args->m_error.SetErrorToErrno();
- goto FINISH;
- }
-#endif
- // Release the master terminal descriptor and pass it off to the
- // ProcessMonitor instance. Similarly stash the inferior pid.
- monitor->m_terminal_fd = terminal.ReleasePrimaryFileDescriptor();
- monitor->m_pid = pid;
-
- // Set the terminal fd to be in non blocking mode (it simplifies the
- // implementation of ProcessFreeBSD::GetSTDOUT to have a non-blocking
- // descriptor to read from).
- if (!EnsureFDFlags(monitor->m_terminal_fd, O_NONBLOCK, args->m_error))
- goto FINISH;
-
- process.SendMessage(ProcessMessage::Attach(pid));
-
-FINISH:
- return args->m_error.Success();
-}
-
-void ProcessMonitor::StartAttachOpThread(AttachArgs *args,
- lldb_private::Status &error) {
- static const char *g_thread_name = "freebsd.op";
-
- if (m_operation_thread && m_operation_thread->IsJoinable())
- return;
-
- llvm::Expected<lldb_private::HostThread> operation_thread =
- ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args);
- if (operation_thread)
- m_operation_thread = *operation_thread;
- else
- error = operation_thread.takeError();
-}
-
-void *ProcessMonitor::AttachOpThread(void *arg) {
- AttachArgs *args = static_cast<AttachArgs *>(arg);
-
- Attach(args);
-
- ServeOperation(args);
- return NULL;
-}
-
-void ProcessMonitor::Attach(AttachArgs *args) {
- lldb::pid_t pid = args->m_pid;
-
- ProcessMonitor *monitor = args->m_monitor;
- ProcessFreeBSD &process = monitor->GetProcess();
-
- if (pid <= 1) {
- args->m_error.SetErrorToGenericError();
- args->m_error.SetErrorString("Attaching to process 1 is not allowed.");
- return;
- }
-
- // Attach to the requested process.
- if (PTRACE(PT_ATTACH, pid, NULL, 0) < 0) {
- args->m_error.SetErrorToErrno();
- return;
- }
-
- int status;
- if ((status = waitpid(pid, NULL, 0)) < 0) {
- args->m_error.SetErrorToErrno();
- return;
- }
-
- process.SendMessage(ProcessMessage::Attach(pid));
-}
-
-size_t
-ProcessMonitor::GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids) {
- lwpid_t *tids;
- int tdcnt;
-
- thread_ids.clear();
-
- tdcnt = PTRACE(PT_GETNUMLWPS, m_pid, NULL, 0);
- if (tdcnt <= 0)
- return 0;
- tids = (lwpid_t *)malloc(tdcnt * sizeof(*tids));
- if (tids == NULL)
- return 0;
- if (PTRACE(PT_GETLWPLIST, m_pid, (void *)tids, tdcnt) < 0) {
- free(tids);
- return 0;
- }
- thread_ids = std::vector<lldb::tid_t>(tids, tids + tdcnt);
- free(tids);
- return thread_ids.size();
-}
-
-bool ProcessMonitor::MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid,
- bool exited, int signal, int status) {
- ProcessMessage message;
- ProcessFreeBSD *process = monitor->m_process;
- assert(process);
- bool stop_monitoring;
- struct ptrace_lwpinfo plwp;
- int ptrace_err;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- if (exited) {
- LLDB_LOGF(log, "ProcessMonitor::%s() got exit signal, tid = %" PRIu64,
- __FUNCTION__, pid);
- message = ProcessMessage::Exit(pid, status);
- process->SendMessage(message);
- return pid == process->GetID();
- }
-
- if (!monitor->GetLwpInfo(pid, &plwp, ptrace_err))
- stop_monitoring = true; // pid is gone. Bail.
- else {
- switch (plwp.pl_siginfo.si_signo) {
- case SIGTRAP:
- message = MonitorSIGTRAP(monitor, &plwp.pl_siginfo, plwp.pl_lwpid);
- break;
-
- default:
- message = MonitorSignal(monitor, &plwp.pl_siginfo, plwp.pl_lwpid);
- break;
- }
-
- process->SendMessage(message);
- stop_monitoring = message.GetKind() == ProcessMessage::eExitMessage;
- }
-
- return stop_monitoring;
-}
-
-ProcessMessage ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
- const siginfo_t *info,
- lldb::tid_t tid) {
- ProcessMessage message;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- assert(monitor);
- assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!");
-
- switch (info->si_code) {
- default:
- assert(false && "Unexpected SIGTRAP code!");
- break;
-
- case (SIGTRAP /* | (PTRACE_EVENT_EXIT << 8) */): {
- // The inferior process is about to exit. Maintain the process in a state
- // of "limbo" until we are explicitly commanded to detach, destroy, resume,
- // etc.
- unsigned long data = 0;
- if (!monitor->GetEventMessage(tid, &data))
- data = -1;
- LLDB_LOGF(log,
- "ProcessMonitor::%s() received exit? event, data = %lx, tid "
- "= %" PRIu64,
- __FUNCTION__, data, tid);
- message = ProcessMessage::Limbo(tid, (data >> 8));
- break;
- }
-
- case 0:
- case TRAP_TRACE:
-#ifdef TRAP_CAP
- // Map TRAP_CAP to a trace trap in the absense of a more specific handler.
- case TRAP_CAP:
-#endif
- LLDB_LOGF(log,
- "ProcessMonitor::%s() received trace event, tid = %" PRIu64
- " : si_code = %d",
- __FUNCTION__, tid, info->si_code);
- message = ProcessMessage::Trace(tid);
- break;
-
- case SI_KERNEL:
- case TRAP_BRKPT:
- if (monitor->m_process->IsSoftwareStepBreakpoint(tid)) {
- LLDB_LOGF(log,
- "ProcessMonitor::%s() received sw single step breakpoint "
- "event, tid = %" PRIu64,
- __FUNCTION__, tid);
- message = ProcessMessage::Trace(tid);
- } else {
- LLDB_LOGF(
- log, "ProcessMonitor::%s() received breakpoint event, tid = %" PRIu64,
- __FUNCTION__, tid);
- message = ProcessMessage::Break(tid);
- }
- break;
- }
-
- return message;
-}
-
-ProcessMessage ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
- const siginfo_t *info,
- lldb::tid_t tid) {
- ProcessMessage message;
- int signo = info->si_signo;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- // POSIX says that process behaviour is undefined after it ignores a SIGFPE,
- // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a kill(2)
- // or raise(3). Similarly for tgkill(2) on FreeBSD.
- //
- // IOW, user generated signals never generate what we consider to be a
- // "crash".
- //
- // Similarly, ACK signals generated by this monitor.
- if (info->si_code == SI_USER) {
- LLDB_LOGF(log,
- "ProcessMonitor::%s() received signal %s with code %s, pid = %d",
- __FUNCTION__,
- monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo),
- "SI_USER", info->si_pid);
- if (info->si_pid == getpid())
- return ProcessMessage::SignalDelivered(tid, signo);
- else
- return ProcessMessage::Signal(tid, signo);
- }
-
- LLDB_LOGF(log, "ProcessMonitor::%s() received signal %s", __FUNCTION__,
- monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo));
-
- switch (signo) {
- case SIGSEGV:
- case SIGILL:
- case SIGFPE:
- case SIGBUS:
- lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
- const auto reason = GetCrashReason(*info);
- if (reason != CrashReason::eInvalidCrashReason) {
- return ProcessMessage::Crash(tid, reason, signo, fault_addr);
- } // else; Use atleast si_signo info for other si_code
- }
-
- // Everything else is "normal" and does not require any special action on our
- // part.
- return ProcessMessage::Signal(tid, signo);
-}
-
-void ProcessMonitor::ServeOperation(OperationArgs *args) {
- ProcessMonitor *monitor = args->m_monitor;
-
- // We are finised with the arguments and are ready to go. Sync with the
- // parent thread and start serving operations on the inferior.
- sem_post(&args->m_semaphore);
-
- for (;;) {
- // wait for next pending operation
- sem_wait(&monitor->m_operation_pending);
-
- monitor->m_operation->Execute(monitor);
-
- // notify calling thread that operation is complete
- sem_post(&monitor->m_operation_done);
- }
-}
-
-void ProcessMonitor::DoOperation(Operation *op) {
- std::lock_guard<std::mutex> guard(m_operation_mutex);
-
- m_operation = op;
-
- // notify operation thread that an operation is ready to be processed
- sem_post(&m_operation_pending);
-
- // wait for operation to complete
- sem_wait(&m_operation_done);
-}
-
-size_t ProcessMonitor::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
- Status &error) {
- size_t result;
- ReadOperation op(vm_addr, buf, size, error, result);
- DoOperation(&op);
- return result;
-}
-
-size_t ProcessMonitor::WriteMemory(lldb::addr_t vm_addr, const void *buf,
- size_t size, lldb_private::Status &error) {
- size_t result;
- WriteOperation op(vm_addr, buf, size, error, result);
- DoOperation(&op);
- return result;
-}
-
-bool ProcessMonitor::ReadRegisterValue(lldb::tid_t tid, unsigned offset,
- const char *reg_name, unsigned size,
- RegisterValue &value) {
- bool result;
- ReadRegOperation op(tid, offset, size, value, result);
- DoOperation(&op);
- return result;
-}
-
-bool ProcessMonitor::WriteRegisterValue(lldb::tid_t tid, unsigned offset,
- const char *reg_name,
- const RegisterValue &value) {
- bool result;
- WriteRegOperation op(tid, offset, value, result);
- DoOperation(&op);
- return result;
-}
-
-bool ProcessMonitor::ReadDebugRegisterValue(
- lldb::tid_t tid, unsigned offset, const char *reg_name, unsigned size,
- lldb_private::RegisterValue &value) {
- bool result;
- ReadDebugRegOperation op(tid, offset, size, value, result);
- DoOperation(&op);
- return result;
-}
-
-bool ProcessMonitor::WriteDebugRegisterValue(
- lldb::tid_t tid, unsigned offset, const char *reg_name,
- const lldb_private::RegisterValue &value) {
- bool result;
- WriteDebugRegOperation op(tid, offset, value, result);
- DoOperation(&op);
- return result;
-}
-
-bool ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size) {
- bool result;
- ReadGPROperation op(tid, buf, result);
- DoOperation(&op);
- return result;
-}
-
-bool ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size) {
- bool result;
- ReadFPROperation op(tid, buf, result);
- DoOperation(&op);
- return result;
-}
-
-bool ProcessMonitor::ReadRegisterSet(lldb::tid_t tid, void *buf,
- size_t buf_size, unsigned int regset) {
- return false;
-}
-
-bool ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size) {
- bool result;
- WriteGPROperation op(tid, buf, result);
- DoOperation(&op);
- return result;
-}
-
-bool ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size) {
- bool result;
- WriteFPROperation op(tid, buf, result);
- DoOperation(&op);
- return result;
-}
-
-bool ProcessMonitor::WriteRegisterSet(lldb::tid_t tid, void *buf,
- size_t buf_size, unsigned int regset) {
- return false;
-}
-
-bool ProcessMonitor::ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value) {
- return false;
-}
-
-bool ProcessMonitor::Resume(lldb::tid_t unused, uint32_t signo) {
- bool result;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- if (log) {
- const char *signame =
- m_process->GetUnixSignals()->GetSignalAsCString(signo);
- if (signame == nullptr)
- signame = "<none>";
- LLDB_LOGF(log,
- "ProcessMonitor::%s() resuming pid %" PRIu64 " with signal %s",
- __FUNCTION__, GetPID(), signame);
- }
- ResumeOperation op(signo, result);
- DoOperation(&op);
- LLDB_LOGF(log, "ProcessMonitor::%s() resuming result = %s", __FUNCTION__,
- result ? "true" : "false");
- return result;
-}
-
-bool ProcessMonitor::SingleStep(lldb::tid_t unused, uint32_t signo) {
- bool result;
- SingleStepOperation op(signo, result);
- DoOperation(&op);
- return result;
-}
-
-bool ProcessMonitor::Kill() {
- bool result;
- KillOperation op(result);
- DoOperation(&op);
- return result;
-}
-
-bool ProcessMonitor::GetLwpInfo(lldb::tid_t tid, void *lwpinfo,
- int &ptrace_err) {
- bool result;
- LwpInfoOperation op(tid, lwpinfo, result, ptrace_err);
- DoOperation(&op);
- return result;
-}
-
-bool ProcessMonitor::ThreadSuspend(lldb::tid_t tid, bool suspend) {
- bool result;
- ThreadSuspendOperation op(tid, suspend, result);
- DoOperation(&op);
- return result;
-}
-
-bool ProcessMonitor::GetEventMessage(lldb::tid_t tid, unsigned long *message) {
- bool result;
- EventMessageOperation op(tid, message, result);
- DoOperation(&op);
- return result;
-}
-
-lldb_private::Status ProcessMonitor::Detach(lldb::tid_t tid) {
- lldb_private::Status error;
- if (tid != LLDB_INVALID_THREAD_ID) {
- DetachOperation op(error);
- DoOperation(&op);
- }
- return error;
-}
-
-bool ProcessMonitor::DupDescriptor(const FileSpec &file_spec, int fd,
- int flags) {
- int target_fd = llvm::sys::RetryAfterSignal(-1, open,
- file_spec.GetCString(), flags, 0666);
-
- if (target_fd == -1)
- return false;
-
- if (dup2(target_fd, fd) == -1)
- return false;
-
- return (close(target_fd) == -1) ? false : true;
-}
-
-void ProcessMonitor::StopMonitoringChildProcess() {
- if (m_monitor_thread && m_monitor_thread->IsJoinable()) {
- m_monitor_thread->Cancel();
- m_monitor_thread->Join(nullptr);
- m_monitor_thread->Reset();
- }
-}
-
-void ProcessMonitor::StopMonitor() {
- StopMonitoringChildProcess();
- StopOpThread();
- sem_destroy(&m_operation_pending);
- sem_destroy(&m_operation_done);
- if (m_terminal_fd >= 0) {
- close(m_terminal_fd);
- m_terminal_fd = -1;
- }
-}
-
-// FIXME: On Linux, when a new thread is created, we receive to notifications,
-// (1) a SIGTRAP|PTRACE_EVENT_CLONE from the main process thread with the child
-// thread id as additional information, and (2) a SIGSTOP|SI_USER from the new
-// child thread indicating that it has is stopped because we attached. We have
-// no guarantee of the order in which these arrive, but we need both before we
-// are ready to proceed. We currently keep a list of threads which have sent
-// the initial SIGSTOP|SI_USER event. Then when we receive the
-// SIGTRAP|PTRACE_EVENT_CLONE notification, if the initial stop has not
-// occurred we call ProcessMonitor::WaitForInitialTIDStop() to wait for it.
-//
-// Right now, the above logic is in ProcessPOSIX, so we need a definition of
-// this function in the FreeBSD ProcessMonitor implementation even if it isn't
-// logically needed.
-//
-// We really should figure out what actually happens on FreeBSD and move the
-// Linux-specific logic out of ProcessPOSIX as needed.
-
-bool ProcessMonitor::WaitForInitialTIDStop(lldb::tid_t tid) { return true; }
-
-void ProcessMonitor::StopOpThread() {
- if (m_operation_thread && m_operation_thread->IsJoinable()) {
- m_operation_thread->Cancel();
- m_operation_thread->Join(nullptr);
- m_operation_thread->Reset();
- }
-}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h
deleted file mode 100644
index c5edfc0be95a..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h
+++ /dev/null
@@ -1,279 +0,0 @@
-//===-- ProcessMonitor.h -------------------------------------- -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ProcessMonitor_H_
-#define liblldb_ProcessMonitor_H_
-
-#include <semaphore.h>
-#include <signal.h>
-
-#include <mutex>
-
-#include "lldb/Host/HostThread.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/lldb-types.h"
-
-namespace lldb_private {
-class Status;
-class Module;
-class Scalar;
-} // End lldb_private namespace.
-
-class ProcessFreeBSD;
-class Operation;
-
-/// \class ProcessMonitor
-/// Manages communication with the inferior (debugee) process.
-///
-/// Upon construction, this class prepares and launches an inferior process
-/// for debugging.
-///
-/// Changes in the inferior process state are propagated to the associated
-/// ProcessFreeBSD instance by calling ProcessFreeBSD::SendMessage with the
-/// appropriate ProcessMessage events.
-///
-/// A purposely minimal set of operations are provided to interrogate and change
-/// the inferior process state.
-class ProcessMonitor {
-public:
- /// Launches an inferior process ready for debugging. Forms the
- /// implementation of Process::DoLaunch.
- ProcessMonitor(ProcessFreeBSD *process, lldb_private::Module *module,
- char const *argv[], lldb_private::Environment env,
- const lldb_private::FileSpec &stdin_file_spec,
- const lldb_private::FileSpec &stdout_file_spec,
- const lldb_private::FileSpec &stderr_file_spec,
- const lldb_private::FileSpec &working_dir,
- const lldb_private::ProcessLaunchInfo &launch_info,
- lldb_private::Status &error);
-
- ProcessMonitor(ProcessFreeBSD *process, lldb::pid_t pid,
- lldb_private::Status &error);
-
- ~ProcessMonitor();
-
- /// Provides the process number of debugee.
- lldb::pid_t GetPID() const { return m_pid; }
-
- /// Returns the process associated with this ProcessMonitor.
- ProcessFreeBSD &GetProcess() { return *m_process; }
-
- /// Returns a file descriptor to the controlling terminal of the inferior
- /// process.
- ///
- /// Reads from this file descriptor yield both the standard output and
- /// standard error of this debugee. Even if stderr and stdout were
- /// redirected on launch it may still happen that data is available on this
- /// descriptor (if the inferior process opens /dev/tty, for example). This
- /// descriptor is closed after a call to StopMonitor().
- ///
- /// If this monitor was attached to an existing process this method returns
- /// -1.
- int GetTerminalFD() const { return m_terminal_fd; }
-
- /// Reads \p size bytes from address @vm_adder in the inferior process
- /// address space.
- ///
- /// This method is provided to implement Process::DoReadMemory.
- size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
- lldb_private::Status &error);
-
- /// Writes \p size bytes from address \p vm_adder in the inferior process
- /// address space.
- ///
- /// This method is provided to implement Process::DoWriteMemory.
- size_t WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
- lldb_private::Status &error);
-
- /// Reads the contents from the register identified by the given
- /// (architecture dependent) offset.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name,
- unsigned size, lldb_private::RegisterValue &value);
-
- /// Writes the given value to the register identified by the given
- /// (architecture dependent) offset.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool WriteRegisterValue(lldb::tid_t tid, unsigned offset,
- const char *reg_name,
- const lldb_private::RegisterValue &value);
-
- /// Reads the contents from the debug register identified by the given
- /// (architecture dependent) offset.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool ReadDebugRegisterValue(lldb::tid_t tid, unsigned offset,
- const char *reg_name, unsigned size,
- lldb_private::RegisterValue &value);
-
- /// Writes the given value to the debug register identified by the given
- /// (architecture dependent) offset.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool WriteDebugRegisterValue(lldb::tid_t tid, unsigned offset,
- const char *reg_name,
- const lldb_private::RegisterValue &value);
- /// Reads all general purpose registers into the specified buffer.
- bool ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
- /// Reads all floating point registers into the specified buffer.
- bool ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
- /// Reads the specified register set into the specified buffer.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size,
- unsigned int regset);
-
- /// Writes all general purpose registers into the specified buffer.
- bool WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
- /// Writes all floating point registers into the specified buffer.
- bool WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
- /// Writes the specified register set into the specified buffer.
- ///
- /// This method is provided for use by RegisterContextFreeBSD derivatives.
- bool WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size,
- unsigned int regset);
-
- /// Reads the value of the thread-specific pointer for a given thread ID.
- bool ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value);
-
- /// Returns current thread IDs in process
- size_t GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids);
-
- /// Writes a ptrace_lwpinfo structure corresponding to the given thread ID
- /// to the memory region pointed to by \p lwpinfo.
- bool GetLwpInfo(lldb::tid_t tid, void *lwpinfo, int &error_no);
-
- /// Suspends or unsuspends a thread prior to process resume or step.
- bool ThreadSuspend(lldb::tid_t tid, bool suspend);
-
- /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
- /// corresponding to the given thread IDto the memory pointed to by @p
- /// message.
- bool GetEventMessage(lldb::tid_t tid, unsigned long *message);
-
- /// Resumes the process. If \p signo is anything but
- /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the process.
- bool Resume(lldb::tid_t unused, uint32_t signo);
-
- /// Single steps the process. If \p signo is anything but
- /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the process.
- bool SingleStep(lldb::tid_t unused, uint32_t signo);
-
- /// Terminate the traced process.
- bool Kill();
-
- lldb_private::Status Detach(lldb::tid_t tid);
-
- void StopMonitor();
-
- // Waits for the initial stop message from a new thread.
- bool WaitForInitialTIDStop(lldb::tid_t tid);
-
-private:
- ProcessFreeBSD *m_process;
-
- llvm::Optional<lldb_private::HostThread> m_operation_thread;
- llvm::Optional<lldb_private::HostThread> m_monitor_thread;
- lldb::pid_t m_pid;
-
- int m_terminal_fd;
-
- // current operation which must be executed on the privileged thread
- Operation *m_operation;
- std::mutex m_operation_mutex;
-
- // semaphores notified when Operation is ready to be processed and when
- // the operation is complete.
- sem_t m_operation_pending;
- sem_t m_operation_done;
-
- struct OperationArgs {
- OperationArgs(ProcessMonitor *monitor);
-
- ~OperationArgs();
-
- ProcessMonitor *m_monitor; // The monitor performing the attach.
- sem_t m_semaphore; // Posted to once operation complete.
- lldb_private::Status m_error; // Set if process operation failed.
- };
-
- /// \class LauchArgs
- ///
- /// Simple structure to pass data to the thread responsible for launching a
- /// child process.
- struct LaunchArgs : OperationArgs {
- LaunchArgs(ProcessMonitor *monitor, lldb_private::Module *module,
- char const **argv, lldb_private::Environment env,
- const lldb_private::FileSpec &stdin_file_spec,
- const lldb_private::FileSpec &stdout_file_spec,
- const lldb_private::FileSpec &stderr_file_spec,
- const lldb_private::FileSpec &working_dir);
-
- ~LaunchArgs();
-
- lldb_private::Module *m_module; // The executable image to launch.
- char const **m_argv; // Process arguments.
- lldb_private::Environment m_env; // Process environment.
- const lldb_private::FileSpec m_stdin_file_spec; // Redirect stdin or empty.
- const lldb_private::FileSpec
- m_stdout_file_spec; // Redirect stdout or empty.
- const lldb_private::FileSpec
- m_stderr_file_spec; // Redirect stderr or empty.
- const lldb_private::FileSpec m_working_dir; // Working directory or empty.
- };
-
- void StartLaunchOpThread(LaunchArgs *args, lldb_private::Status &error);
-
- static void *LaunchOpThread(void *arg);
-
- static bool Launch(LaunchArgs *args);
-
- struct AttachArgs : OperationArgs {
- AttachArgs(ProcessMonitor *monitor, lldb::pid_t pid);
-
- ~AttachArgs();
-
- lldb::pid_t m_pid; // pid of the process to be attached.
- };
-
- void StartAttachOpThread(AttachArgs *args, lldb_private::Status &error);
-
- static void *AttachOpThread(void *args);
-
- static void Attach(AttachArgs *args);
-
- static void ServeOperation(OperationArgs *args);
-
- static bool DupDescriptor(const lldb_private::FileSpec &file_spec, int fd,
- int flags);
-
- static bool MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid,
- bool exited, int signal, int status);
-
- static ProcessMessage MonitorSIGTRAP(ProcessMonitor *monitor,
- const siginfo_t *info, lldb::pid_t pid);
-
- static ProcessMessage MonitorSignal(ProcessMonitor *monitor,
- const siginfo_t *info, lldb::pid_t pid);
-
- void DoOperation(Operation *op);
-
- /// Stops the child monitor thread.
- void StopMonitoringChildProcess();
-
- /// Stops the operation thread used to attach/launch a process.
- void StopOpThread();
-};
-
-#endif // #ifndef liblldb_ProcessMonitor_H_
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
deleted file mode 100644
index cf52a065232c..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//===-- RegisterContextPOSIX.h --------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextPOSIX_H_
-#define liblldb_RegisterContextPOSIX_H_
-
-#include "Plugins/Process/Utility/RegisterInfoInterface.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Utility/ArchSpec.h"
-
-/// \class POSIXBreakpointProtocol
-///
-/// Extends RegisterClass with a few virtual operations useful on POSIX.
-class POSIXBreakpointProtocol {
-public:
- POSIXBreakpointProtocol() { m_watchpoints_initialized = false; }
- virtual ~POSIXBreakpointProtocol() {}
-
- /// Updates the register state of the associated thread after hitting a
- /// breakpoint (if that make sense for the architecture). Default
- /// implementation simply returns true for architectures which do not
- /// require any update.
- ///
- /// \return
- /// True if the operation succeeded and false otherwise.
- virtual bool UpdateAfterBreakpoint() = 0;
-
- /// Determines the index in lldb's register file given a kernel byte offset.
- virtual unsigned GetRegisterIndexFromOffset(unsigned offset) = 0;
-
- // Checks to see if a watchpoint specified by hw_index caused the inferior
- // to stop.
- virtual bool IsWatchpointHit(uint32_t hw_index) = 0;
-
- // Resets any watchpoints that have been hit.
- virtual bool ClearWatchpointHits() = 0;
-
- // Returns the watchpoint address associated with a watchpoint hardware
- // index.
- virtual lldb::addr_t GetWatchpointAddress(uint32_t hw_index) = 0;
-
- virtual bool IsWatchpointVacant(uint32_t hw_index) = 0;
-
- virtual bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
- bool read, bool write,
- uint32_t hw_index) = 0;
-
- // From lldb_private::RegisterContext
- virtual uint32_t NumSupportedHardwareWatchpoints() = 0;
-
- // Force m_watchpoints_initialized to TRUE
- void ForceWatchpointsInitialized() { m_watchpoints_initialized = true; }
-
-protected:
- bool m_watchpoints_initialized;
-};
-
-#endif // #ifndef liblldb_RegisterContextPOSIX_H_
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
deleted file mode 100644
index 4216f68faf5c..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
+++ /dev/null
@@ -1,259 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_arm.cpp ------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===---------------------------------------------------------------------===//
-
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/RegisterValue.h"
-
-#include "ProcessFreeBSD.h"
-#include "ProcessMonitor.h"
-#include "RegisterContextPOSIXProcessMonitor_arm.h"
-#include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h"
-
-using namespace lldb_private;
-using namespace lldb;
-
-#define REG_CONTEXT_SIZE (GetGPRSize())
-
-RegisterContextPOSIXProcessMonitor_arm::RegisterContextPOSIXProcessMonitor_arm(
- Thread &thread, uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : RegisterContextPOSIX_arm(thread, concrete_frame_idx, register_info) {}
-
-ProcessMonitor &RegisterContextPOSIXProcessMonitor_arm::GetMonitor() {
- ProcessSP base = CalculateProcess();
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
- return process->GetMonitor();
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::ReadGPR() {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_arm, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::ReadFPR() {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadFPR(m_thread.GetID(), &m_fpr, sizeof(m_fpr));
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::WriteGPR() {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &m_gpr_arm, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::WriteFPR() {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteFPR(m_thread.GetID(), &m_fpr, sizeof(m_fpr));
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::ReadRegister(
- const unsigned reg, RegisterValue &value) {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
- GetRegisterName(reg), GetRegisterSize(reg),
- value);
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::WriteRegister(
- const unsigned reg, const RegisterValue &value) {
- unsigned reg_to_write = reg;
- RegisterValue value_to_write = value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info->invalidate_regs &&
- (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- if (ReadRegister(full_reg_info, full_value)) {
- Status error;
- ByteOrder byte_order = GetByteOrder();
- uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData(
- full_reg_info, dst, sizeof(dst), byte_order, error);
- if (error.Success() && dest_size) {
- uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = value.GetAsMemoryData(
- reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size)) {
- // Copy the src bytes to the destination.
- memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
- }
- }
-
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteRegisterValue(
- m_thread.GetID(), GetRegisterOffset(reg_to_write),
- GetRegisterName(reg_to_write), value_to_write);
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::ReadRegister(
- const RegisterInfo *reg_info, RegisterValue &value) {
- if (!reg_info)
- return false;
-
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
- if (IsFPR(reg)) {
- if (!ReadFPR())
- return false;
- } else {
- return ReadRegister(reg, value);
- }
-
- // Get pointer to m_fpr variable and set the data from it.
- assert(reg_info->byte_offset < sizeof m_fpr);
- uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
- switch (reg_info->byte_size) {
- case 2:
- value.SetUInt16(*(uint16_t *)src);
- return true;
- case 4:
- value.SetUInt32(*(uint32_t *)src);
- return true;
- case 8:
- value.SetUInt64(*(uint64_t *)src);
- return true;
- default:
- assert(false && "Unhandled data size.");
- return false;
- }
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::WriteRegister(
- const RegisterInfo *reg_info, const RegisterValue &value) {
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
- if (IsGPR(reg)) {
- return WriteRegister(reg, value);
- } else if (IsFPR(reg)) {
- return WriteFPR();
- }
-
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::ReadAllRegisterValues(
- DataBufferSP &data_sp) {
- bool success = false;
- data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- if (ReadGPR() && ReadFPR()) {
- uint8_t *dst = data_sp->GetBytes();
- success = dst != 0;
-
- if (success) {
- ::memcpy(dst, &m_gpr_arm, GetGPRSize());
- dst += GetGPRSize();
- ::memcpy(dst, &m_fpr, sizeof(m_fpr));
- }
- }
- return success;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::WriteAllRegisterValues(
- const DataBufferSP &data_sp) {
- bool success = false;
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
- uint8_t *src = data_sp->GetBytes();
- if (src) {
- ::memcpy(&m_gpr_arm, src, GetGPRSize());
-
- if (WriteGPR()) {
- src += GetGPRSize();
- ::memcpy(&m_fpr, src, sizeof(m_fpr));
-
- success = WriteFPR();
- }
- }
- }
- return success;
-}
-
-uint32_t RegisterContextPOSIXProcessMonitor_arm::SetHardwareWatchpoint(
- addr_t addr, size_t size, bool read, bool write) {
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- uint32_t hw_index;
-
- for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
- if (IsWatchpointVacant(hw_index))
- return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
- }
-
- return LLDB_INVALID_INDEX32;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::ClearHardwareWatchpoint(
- uint32_t hw_index) {
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::HardwareSingleStep(bool enable) {
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::UpdateAfterBreakpoint() {
- lldb::addr_t pc;
-
- if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
- return false;
-
- return true;
-}
-
-unsigned RegisterContextPOSIXProcessMonitor_arm::GetRegisterIndexFromOffset(
- unsigned offset) {
- unsigned reg;
- for (reg = 0; reg < k_num_registers_arm; reg++) {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < k_num_registers_arm && "Invalid register offset.");
- return reg;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::IsWatchpointHit(
- uint32_t hw_index) {
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::ClearWatchpointHits() {
- return false;
-}
-
-addr_t RegisterContextPOSIXProcessMonitor_arm::GetWatchpointAddress(
- uint32_t hw_index) {
- return LLDB_INVALID_ADDRESS;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::IsWatchpointVacant(
- uint32_t hw_index) {
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::SetHardwareWatchpointWithIndex(
- addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
- return false;
-}
-
-uint32_t
-RegisterContextPOSIXProcessMonitor_arm::NumSupportedHardwareWatchpoints() {
- return 0;
-}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h
deleted file mode 100644
index b376967df99c..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h
+++ /dev/null
@@ -1,76 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_arm.h --------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextPOSIXProcessMonitor_arm_H_
-#define liblldb_RegisterContextPOSIXProcessMonitor_arm_H_
-
-#include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h"
-#include "RegisterContextPOSIX.h"
-
-class RegisterContextPOSIXProcessMonitor_arm : public RegisterContextPOSIX_arm,
- public POSIXBreakpointProtocol {
-public:
- RegisterContextPOSIXProcessMonitor_arm(
- lldb_private::Thread &thread, uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
-
-protected:
- bool ReadGPR();
-
- bool ReadFPR();
-
- bool WriteGPR();
-
- bool WriteFPR();
-
- // lldb_private::RegisterContext
- bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
-
- bool WriteRegister(const unsigned reg,
- const lldb_private::RegisterValue &value);
-
- bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value);
-
- bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value);
-
- bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
-
- bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
-
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
- bool write);
-
- bool ClearHardwareWatchpoint(uint32_t hw_index);
-
- bool HardwareSingleStep(bool enable);
-
- // POSIXBreakpointProtocol
- bool UpdateAfterBreakpoint();
-
- unsigned GetRegisterIndexFromOffset(unsigned offset);
-
- bool IsWatchpointHit(uint32_t hw_index);
-
- bool ClearWatchpointHits();
-
- lldb::addr_t GetWatchpointAddress(uint32_t hw_index);
-
- bool IsWatchpointVacant(uint32_t hw_index);
-
- bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
- bool write, uint32_t hw_index);
-
- uint32_t NumSupportedHardwareWatchpoints();
-
-private:
- ProcessMonitor &GetMonitor();
-};
-
-#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp
deleted file mode 100644
index d3eafae1e6de..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_arm64.cpp ----------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===---------------------------------------------------------------------===//
-
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/RegisterValue.h"
-
-#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
-#include "ProcessFreeBSD.h"
-#include "ProcessMonitor.h"
-#include "RegisterContextPOSIXProcessMonitor_arm64.h"
-
-#define REG_CONTEXT_SIZE (GetGPRSize())
-
-using namespace lldb;
-using namespace lldb_private;
-
-RegisterContextPOSIXProcessMonitor_arm64::
- RegisterContextPOSIXProcessMonitor_arm64(
- lldb_private::Thread &thread,
- std::unique_ptr<RegisterInfoPOSIX_arm64> register_info)
- : RegisterContextPOSIX_arm64(thread, std::move(register_info)) {}
-
-ProcessMonitor &RegisterContextPOSIXProcessMonitor_arm64::GetMonitor() {
- lldb::ProcessSP base = CalculateProcess();
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
- return process->GetMonitor();
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::ReadGPR() {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_arm64, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::ReadFPR() {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadFPR(m_thread.GetID(), &m_fpr, sizeof m_fpr);
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::WriteGPR() {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &m_gpr_arm64, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::WriteFPR() {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteFPR(m_thread.GetID(), &m_fpr, sizeof m_fpr);
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::ReadRegister(
- const unsigned reg, lldb_private::RegisterValue &value) {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
- GetRegisterName(reg), GetRegisterSize(reg),
- value);
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::WriteRegister(
- const unsigned reg, const lldb_private::RegisterValue &value) {
- unsigned reg_to_write = reg;
- lldb_private::RegisterValue value_to_write = value;
-
- // Check if this is a subregister of a full register.
- const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info->invalidate_regs &&
- (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
- lldb_private::RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const lldb_private::RegisterInfo *full_reg_info =
- GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- if (ReadRegister(full_reg_info, full_value)) {
- lldb_private::Status error;
- lldb::ByteOrder byte_order = GetByteOrder();
- uint8_t dst[lldb_private::RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData(
- full_reg_info, dst, sizeof(dst), byte_order, error);
- if (error.Success() && dest_size) {
- uint8_t src[lldb_private::RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = value.GetAsMemoryData(
- reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size)) {
- // Copy the src bytes to the destination.
- ::memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
- }
- }
-
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteRegisterValue(
- m_thread.GetID(), GetRegisterOffset(reg_to_write),
- GetRegisterName(reg_to_write), value_to_write);
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::ReadRegister(
- const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value) {
- if (!reg_info)
- return false;
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
-
- if (IsFPR(reg)) {
- if (!ReadFPR())
- return false;
- } else {
- uint32_t full_reg = reg;
- bool is_subreg = reg_info->invalidate_regs &&
- (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
- if (is_subreg) {
- // Read the full aligned 64-bit register.
- full_reg = reg_info->invalidate_regs[0];
- }
- return ReadRegister(full_reg, value);
- }
-
- // Get pointer to m_fpr variable and set the data from it.
- assert(reg_info->byte_offset < sizeof m_fpr);
- uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
- switch (reg_info->byte_size) {
- case 2:
- value.SetUInt16(*(uint16_t *)src);
- return true;
- case 4:
- value.SetUInt32(*(uint32_t *)src);
- return true;
- case 8:
- value.SetUInt64(*(uint64_t *)src);
- return true;
- default:
- assert(false && "Unhandled data size.");
- return false;
- }
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::WriteRegister(
- const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value) {
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
-
- if (IsGPR(reg))
- return WriteRegister(reg, value);
-
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
- bool success = false;
- data_sp.reset(new lldb_private::DataBufferHeap(REG_CONTEXT_SIZE, 0));
- if (ReadGPR() && ReadFPR()) {
- uint8_t *dst = data_sp->GetBytes();
- success = dst != 0;
-
- if (success) {
- ::memcpy(dst, &m_gpr_arm64, GetGPRSize());
- dst += GetGPRSize();
- ::memcpy(dst, &m_fpr, sizeof m_fpr);
- }
- }
- return success;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::WriteAllRegisterValues(
- const lldb::DataBufferSP &data_sp) {
- bool success = false;
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
- uint8_t *src = data_sp->GetBytes();
- if (src) {
- ::memcpy(&m_gpr_arm64, src, GetGPRSize());
- if (WriteGPR()) {
- src += GetGPRSize();
- ::memcpy(&m_fpr, src, sizeof m_fpr);
- success = WriteFPR();
- }
- }
- }
- return success;
-}
-
-uint32_t RegisterContextPOSIXProcessMonitor_arm64::SetHardwareWatchpoint(
- lldb::addr_t addr, size_t size, bool read, bool write) {
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- uint32_t hw_index;
-
- for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
- if (IsWatchpointVacant(hw_index))
- return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
- }
-
- return LLDB_INVALID_INDEX32;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::ClearHardwareWatchpoint(
- uint32_t hw_index) {
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::HardwareSingleStep(bool enable) {
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::UpdateAfterBreakpoint() {
- if (GetPC() == LLDB_INVALID_ADDRESS)
- return false;
-
- return true;
-}
-
-unsigned RegisterContextPOSIXProcessMonitor_arm64::GetRegisterIndexFromOffset(
- unsigned offset) {
- unsigned reg;
- for (reg = 0; reg < k_num_registers_arm64; reg++) {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < k_num_registers_arm64 && "Invalid register offset.");
- return reg;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::IsWatchpointHit(
- uint32_t hw_index) {
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::ClearWatchpointHits() {
- return false;
-}
-
-lldb::addr_t RegisterContextPOSIXProcessMonitor_arm64::GetWatchpointAddress(
- uint32_t hw_index) {
- return LLDB_INVALID_ADDRESS;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::IsWatchpointVacant(
- uint32_t hw_index) {
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::SetHardwareWatchpointWithIndex(
- lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
- return false;
-}
-
-uint32_t
-RegisterContextPOSIXProcessMonitor_arm64::NumSupportedHardwareWatchpoints() {
- return 0;
-}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h
deleted file mode 100644
index f100d905e28f..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h
+++ /dev/null
@@ -1,77 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_arm64.h --------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextPOSIXProcessMonitor_arm64_H_
-#define liblldb_RegisterContextPOSIXProcessMonitor_arm64_H_
-
-#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
-#include "RegisterContextPOSIX.h"
-
-class RegisterContextPOSIXProcessMonitor_arm64
- : public RegisterContextPOSIX_arm64,
- public POSIXBreakpointProtocol {
-public:
- RegisterContextPOSIXProcessMonitor_arm64(
- lldb_private::Thread &thread,
- std::unique_ptr<RegisterInfoPOSIX_arm64> register_info);
-
-protected:
- bool ReadGPR();
-
- bool ReadFPR();
-
- bool WriteGPR();
-
- bool WriteFPR();
-
- // lldb_private::RegisterContext
- bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
-
- bool WriteRegister(const unsigned reg,
- const lldb_private::RegisterValue &value);
-
- bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value);
-
- bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value);
-
- bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
-
- bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
-
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
- bool write);
-
- bool ClearHardwareWatchpoint(uint32_t hw_index);
-
- bool HardwareSingleStep(bool enable);
-
- // POSIXBreakpointProtocol
- bool UpdateAfterBreakpoint();
-
- unsigned GetRegisterIndexFromOffset(unsigned offset);
-
- bool IsWatchpointHit(uint32_t hw_index);
-
- bool ClearWatchpointHits();
-
- lldb::addr_t GetWatchpointAddress(uint32_t hw_index);
-
- bool IsWatchpointVacant(uint32_t hw_index);
-
- bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
- bool write, uint32_t hw_index);
-
- uint32_t NumSupportedHardwareWatchpoints();
-
-private:
- ProcessMonitor &GetMonitor();
-};
-
-#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
deleted file mode 100644
index 23c76f234c8e..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_mips64.cpp ---------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/RegisterValue.h"
-
-#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h"
-#include "ProcessFreeBSD.h"
-#include "ProcessMonitor.h"
-#include "RegisterContextPOSIXProcessMonitor_mips64.h"
-
-using namespace lldb_private;
-using namespace lldb;
-
-#define REG_CONTEXT_SIZE (GetGPRSize())
-
-RegisterContextPOSIXProcessMonitor_mips64::
- RegisterContextPOSIXProcessMonitor_mips64(
- Thread &thread, uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : RegisterContextPOSIX_mips64(thread, concrete_frame_idx, register_info) {}
-
-ProcessMonitor &RegisterContextPOSIXProcessMonitor_mips64::GetMonitor() {
- ProcessSP base = CalculateProcess();
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
- return process->GetMonitor();
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::ReadGPR() {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::ReadFPR() {
- // XXX not yet implemented
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::WriteGPR() {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::WriteFPR() {
- // XXX not yet implemented
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(
- const unsigned reg, RegisterValue &value) {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
- GetRegisterName(reg), GetRegisterSize(reg),
- value);
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(
- const unsigned reg, const RegisterValue &value) {
- unsigned reg_to_write = reg;
- RegisterValue value_to_write = value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info->invalidate_regs &&
- (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- if (ReadRegister(full_reg_info, full_value)) {
- Status error;
- ByteOrder byte_order = GetByteOrder();
- uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData(
- full_reg_info, dst, sizeof(dst), byte_order, error);
- if (error.Success() && dest_size) {
- uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = value.GetAsMemoryData(
- reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size)) {
- // Copy the src bytes to the destination.
- memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
- }
- }
-
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteRegisterValue(
- m_thread.GetID(), GetRegisterOffset(reg_to_write),
- GetRegisterName(reg_to_write), value_to_write);
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(
- const RegisterInfo *reg_info, RegisterValue &value) {
- if (!reg_info)
- return false;
-
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
- if (IsFPR(reg)) {
- if (!ReadFPR())
- return false;
- } else {
- uint32_t full_reg = reg;
- bool is_subreg = reg_info->invalidate_regs &&
- (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
- if (is_subreg) {
- // Read the full aligned 64-bit register.
- full_reg = reg_info->invalidate_regs[0];
- }
-
- bool success = ReadRegister(full_reg, value);
-
- if (success) {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned
- // value one byte to the right.
- if (is_subreg && (reg_info->byte_offset & 0x1))
- value.SetUInt64(value.GetAsUInt64() >> 8);
-
- // If our return byte size was greater than the return value reg size,
- // then use the type specified by reg_info rather than the uint64_t
- // default
- if (value.GetByteSize() > reg_info->byte_size)
- value.SetType(reg_info);
- }
- return success;
- }
-
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(
- const RegisterInfo *reg_info, const RegisterValue &value) {
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
- if (IsGPR(reg))
- return WriteRegister(reg, value);
-
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::ReadAllRegisterValues(
- DataBufferSP &data_sp) {
- bool success = false;
- data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- if (ReadGPR() && ReadFPR()) {
- uint8_t *dst = data_sp->GetBytes();
- success = dst != 0;
-
- if (success) {
- ::memcpy(dst, &m_gpr_mips64, GetGPRSize());
- }
- }
- return success;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::WriteAllRegisterValues(
- const DataBufferSP &data_sp) {
- bool success = false;
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
- uint8_t *src = data_sp->GetBytes();
- if (src) {
- ::memcpy(&m_gpr_mips64, src, GetGPRSize());
-
- if (WriteGPR()) {
- src += GetGPRSize();
- }
- }
- }
- return success;
-}
-
-uint32_t RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpoint(
- addr_t addr, size_t size, bool read, bool write) {
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- uint32_t hw_index;
-
- for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
- if (IsWatchpointVacant(hw_index))
- return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
- }
-
- return LLDB_INVALID_INDEX32;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::ClearHardwareWatchpoint(
- uint32_t hw_index) {
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::HardwareSingleStep(
- bool enable) {
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::UpdateAfterBreakpoint() {
- // PC points one byte past the int3 responsible for the breakpoint.
- lldb::addr_t pc;
-
- if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
- return false;
-
- SetPC(pc - 1);
- return true;
-}
-
-unsigned RegisterContextPOSIXProcessMonitor_mips64::GetRegisterIndexFromOffset(
- unsigned offset) {
- unsigned reg;
- for (reg = 0; reg < k_num_registers_mips64; reg++) {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < k_num_registers_mips64 && "Invalid register offset.");
- return reg;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointHit(
- uint32_t hw_index) {
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::ClearWatchpointHits() {
- return false;
-}
-
-addr_t RegisterContextPOSIXProcessMonitor_mips64::GetWatchpointAddress(
- uint32_t hw_index) {
- return LLDB_INVALID_ADDRESS;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointVacant(
- uint32_t hw_index) {
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpointWithIndex(
- addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
- return false;
-}
-
-uint32_t
-RegisterContextPOSIXProcessMonitor_mips64::NumSupportedHardwareWatchpoints() {
- return 0;
-}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h
deleted file mode 100644
index a482cd3f1e1c..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_mips64.h -------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextPOSIXProcessMonitor_mips64_H_
-#define liblldb_RegisterContextPOSIXProcessMonitor_mips64_H_
-
-#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h"
-#include "Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h"
-#include "RegisterContextPOSIX.h"
-
-class RegisterContextPOSIXProcessMonitor_mips64
- : public RegisterContextPOSIX_mips64,
- public POSIXBreakpointProtocol {
-public:
- RegisterContextPOSIXProcessMonitor_mips64(
- lldb_private::Thread &thread, uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
-
-protected:
- bool ReadGPR();
-
- bool ReadFPR();
-
- bool WriteGPR();
-
- bool WriteFPR();
-
- // lldb_private::RegisterContext
- bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
-
- bool WriteRegister(const unsigned reg,
- const lldb_private::RegisterValue &value);
-
- bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value);
-
- bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value);
-
- bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
-
- bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
-
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
- bool write);
-
- bool ClearHardwareWatchpoint(uint32_t hw_index);
-
- bool HardwareSingleStep(bool enable);
-
- // POSIXBreakpointProtocol
- bool UpdateAfterBreakpoint();
-
- unsigned GetRegisterIndexFromOffset(unsigned offset);
-
- bool IsWatchpointHit(uint32_t hw_index);
-
- bool ClearWatchpointHits();
-
- lldb::addr_t GetWatchpointAddress(uint32_t hw_index);
-
- bool IsWatchpointVacant(uint32_t hw_index);
-
- bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
- bool write, uint32_t hw_index);
-
- uint32_t NumSupportedHardwareWatchpoints();
-
-private:
- uint64_t
- m_gpr_mips64[k_num_gpr_registers_mips64]; // general purpose registers.
- ProcessMonitor &GetMonitor();
-};
-
-#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
deleted file mode 100644
index f8342775a81b..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
+++ /dev/null
@@ -1,274 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_powerpc.cpp --------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/RegisterValue.h"
-
-#include "ProcessFreeBSD.h"
-#include "ProcessMonitor.h"
-#include "RegisterContextPOSIXProcessMonitor_powerpc.h"
-#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
-
-using namespace lldb_private;
-using namespace lldb;
-
-#define REG_CONTEXT_SIZE (GetGPRSize())
-
-RegisterContextPOSIXProcessMonitor_powerpc::
- RegisterContextPOSIXProcessMonitor_powerpc(
- Thread &thread, uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : RegisterContextPOSIX_powerpc(thread, concrete_frame_idx, register_info) {}
-
-ProcessMonitor &RegisterContextPOSIXProcessMonitor_powerpc::GetMonitor() {
- ProcessSP base = CalculateProcess();
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
- return process->GetMonitor();
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::ReadGPR() {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::ReadFPR() {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadFPR(m_thread.GetID(), &m_fpr_powerpc,
- sizeof(m_fpr_powerpc));
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::ReadVMX() {
- // XXX: Need a way to read/write process VMX registers with ptrace.
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::WriteGPR() {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::WriteFPR() {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteFPR(m_thread.GetID(), &m_fpr_powerpc,
- sizeof(m_fpr_powerpc));
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::WriteVMX() {
- // XXX: Need a way to read/write process VMX registers with ptrace.
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(
- const unsigned reg, RegisterValue &value) {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
- GetRegisterName(reg), GetRegisterSize(reg),
- value);
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(
- const unsigned reg, const RegisterValue &value) {
- unsigned reg_to_write = reg;
- RegisterValue value_to_write = value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info->invalidate_regs &&
- (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- if (ReadRegister(full_reg_info, full_value)) {
- Status error;
- ByteOrder byte_order = GetByteOrder();
- uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData(
- full_reg_info, dst, sizeof(dst), byte_order, error);
- if (error.Success() && dest_size) {
- uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = value.GetAsMemoryData(
- reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size)) {
- // Copy the src bytes to the destination.
- memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
- }
- }
-
- ProcessMonitor &monitor = GetMonitor();
- // Account for the fact that 32-bit targets on powerpc64 really use 64-bit
- // registers in ptrace, but expose here 32-bit registers with a higher
- // offset.
- uint64_t offset = GetRegisterOffset(reg_to_write);
- offset &= ~(sizeof(uintptr_t) - 1);
- return monitor.WriteRegisterValue(
- m_thread.GetID(), offset, GetRegisterName(reg_to_write), value_to_write);
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(
- const RegisterInfo *reg_info, RegisterValue &value) {
- if (!reg_info)
- return false;
-
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
- if (IsFPR(reg)) {
- if (!ReadFPR())
- return false;
- uint8_t *src = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
- value.SetUInt64(*(uint64_t *)src);
- } else if (IsGPR(reg)) {
- bool success = ReadRegister(reg, value);
-
- if (success) {
- // If our return byte size was greater than the return value reg size,
- // then use the type specified by reg_info rather than the uint64_t
- // default
- if (value.GetByteSize() > reg_info->byte_size)
- value.SetType(reg_info);
- }
- return success;
- }
-
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(
- const RegisterInfo *reg_info, const RegisterValue &value) {
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
- if (IsGPR(reg)) {
- return WriteRegister(reg, value);
- } else if (IsFPR(reg)) {
- assert(reg_info->byte_offset < sizeof(m_fpr_powerpc));
- uint8_t *dst = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
- *(uint64_t *)dst = value.GetAsUInt64();
- return WriteFPR();
- }
-
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::ReadAllRegisterValues(
- DataBufferSP &data_sp) {
- bool success = false;
- data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- if (ReadGPR() && ReadFPR()) {
- uint8_t *dst = data_sp->GetBytes();
- success = dst != 0;
-
- if (success) {
- ::memcpy(dst, &m_gpr_powerpc, GetGPRSize());
- dst += GetGPRSize();
- }
- }
- return success;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::WriteAllRegisterValues(
- const DataBufferSP &data_sp) {
- bool success = false;
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
- uint8_t *src = data_sp->GetBytes();
- if (src) {
- ::memcpy(&m_gpr_powerpc, src, GetGPRSize());
-
- if (WriteGPR()) {
- src += GetGPRSize();
- ::memcpy(&m_fpr_powerpc, src, sizeof(m_fpr_powerpc));
-
- success = WriteFPR();
- }
- }
- }
- return success;
-}
-
-uint32_t RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpoint(
- addr_t addr, size_t size, bool read, bool write) {
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- uint32_t hw_index;
-
- for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
- if (IsWatchpointVacant(hw_index))
- return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
- }
-
- return LLDB_INVALID_INDEX32;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::ClearHardwareWatchpoint(
- uint32_t hw_index) {
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::HardwareSingleStep(
- bool enable) {
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::UpdateAfterBreakpoint() {
- lldb::addr_t pc;
-
- if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
- return false;
-
- return true;
-}
-
-unsigned RegisterContextPOSIXProcessMonitor_powerpc::GetRegisterIndexFromOffset(
- unsigned offset) {
- unsigned reg;
- for (reg = 0; reg < k_num_registers_powerpc; reg++) {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < k_num_registers_powerpc && "Invalid register offset.");
- return reg;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointHit(
- uint32_t hw_index) {
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::ClearWatchpointHits() {
- return false;
-}
-
-addr_t RegisterContextPOSIXProcessMonitor_powerpc::GetWatchpointAddress(
- uint32_t hw_index) {
- return LLDB_INVALID_ADDRESS;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointVacant(
- uint32_t hw_index) {
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpointWithIndex(
- addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
- return false;
-}
-
-uint32_t
-RegisterContextPOSIXProcessMonitor_powerpc::NumSupportedHardwareWatchpoints() {
- return 0;
-}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h
deleted file mode 100644
index 17b649feebf1..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h
+++ /dev/null
@@ -1,84 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_powerpc.h -------------*- C++
-//-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextPOSIXProcessMonitor_powerpc_H_
-#define liblldb_RegisterContextPOSIXProcessMonitor_powerpc_H_
-
-#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
-#include "RegisterContextPOSIX.h"
-
-class RegisterContextPOSIXProcessMonitor_powerpc
- : public RegisterContextPOSIX_powerpc,
- public POSIXBreakpointProtocol {
-public:
- RegisterContextPOSIXProcessMonitor_powerpc(
- lldb_private::Thread &thread, uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
-
-protected:
- bool IsVMX();
-
- bool ReadGPR();
-
- bool ReadFPR();
-
- bool ReadVMX();
-
- bool WriteGPR();
-
- bool WriteFPR();
-
- bool WriteVMX();
-
- // lldb_private::RegisterContext
- bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
-
- bool WriteRegister(const unsigned reg,
- const lldb_private::RegisterValue &value);
-
- bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value);
-
- bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value);
-
- bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
-
- bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
-
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
- bool write);
-
- bool ClearHardwareWatchpoint(uint32_t hw_index);
-
- bool HardwareSingleStep(bool enable);
-
- // POSIXBreakpointProtocol
- bool UpdateAfterBreakpoint();
-
- unsigned GetRegisterIndexFromOffset(unsigned offset);
-
- bool IsWatchpointHit(uint32_t hw_index);
-
- bool ClearWatchpointHits();
-
- lldb::addr_t GetWatchpointAddress(uint32_t hw_index);
-
- bool IsWatchpointVacant(uint32_t hw_index);
-
- bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
- bool write, uint32_t hw_index);
-
- uint32_t NumSupportedHardwareWatchpoints();
-
-private:
- ProcessMonitor &GetMonitor();
-};
-
-#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
deleted file mode 100644
index b1739e1e3bd8..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
+++ /dev/null
@@ -1,613 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_x86.cpp ------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/RegisterValue.h"
-
-#include "Plugins/Process/FreeBSD/ProcessFreeBSD.h"
-#include "Plugins/Process/FreeBSD/ProcessMonitor.h"
-#include "RegisterContextPOSIXProcessMonitor_x86.h"
-
-using namespace lldb_private;
-using namespace lldb;
-
-// Support ptrace extensions even when compiled without required kernel support
-#ifndef NT_X86_XSTATE
-#define NT_X86_XSTATE 0x202
-#endif
-
-#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof(FPR))
-
-static uint32_t size_and_rw_bits(size_t size, bool read, bool write) {
- uint32_t rw;
-
- if (read)
- rw = 0x3; // READ or READ/WRITE
- else if (write)
- rw = 0x1; // WRITE
- else
- assert(0 && "read and write cannot both be false");
-
- switch (size) {
- case 1:
- return rw;
- case 2:
- return (0x1 << 2) | rw;
- case 4:
- return (0x3 << 2) | rw;
- case 8:
- return (0x2 << 2) | rw;
- default:
- assert(0 && "invalid size, must be one of 1, 2, 4, or 8");
- return 0; // Unreachable. Just to silence compiler.
- }
-}
-
-RegisterContextPOSIXProcessMonitor_x86_64::
- RegisterContextPOSIXProcessMonitor_x86_64(
- Thread &thread, uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : RegisterContextPOSIX_x86(thread, concrete_frame_idx, register_info) {
- // Store byte offset of fctrl (i.e. first register of FPR) wrt 'UserArea'
- const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
- m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
-
- m_iovec.iov_base = &m_fpr.xsave;
- m_iovec.iov_len = sizeof(m_fpr.xsave);
-}
-
-ProcessMonitor &RegisterContextPOSIXProcessMonitor_x86_64::GetMonitor() {
- ProcessSP base = CalculateProcess();
- ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
- return process->GetMonitor();
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::ReadGPR() {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::ReadFPR() {
- ProcessMonitor &monitor = GetMonitor();
- if (GetFPRType() == eFXSAVE)
- return monitor.ReadFPR(m_thread.GetID(), &m_fpr.fxsave,
- sizeof(m_fpr.fxsave));
-
- if (GetFPRType() == eXSAVE)
- return monitor.ReadRegisterSet(m_thread.GetID(), &m_iovec,
- sizeof(m_fpr.xsave), NT_X86_XSTATE);
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::WriteGPR() {
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::WriteFPR() {
- ProcessMonitor &monitor = GetMonitor();
- if (GetFPRType() == eFXSAVE)
- return monitor.WriteFPR(m_thread.GetID(), &m_fpr.fxsave,
- sizeof(m_fpr.fxsave));
-
- if (GetFPRType() == eXSAVE)
- return monitor.WriteRegisterSet(m_thread.GetID(), &m_iovec,
- sizeof(m_fpr.xsave), NT_X86_XSTATE);
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(
- const unsigned reg, RegisterValue &value) {
- ProcessMonitor &monitor = GetMonitor();
-
-#if defined(__FreeBSD__)
- if (reg >= m_reg_info.first_dr)
- return monitor.ReadDebugRegisterValue(
- m_thread.GetID(), GetRegisterOffset(reg), GetRegisterName(reg),
- GetRegisterSize(reg), value);
-#endif
- return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
- GetRegisterName(reg), GetRegisterSize(reg),
- value);
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(
- const unsigned reg, const RegisterValue &value) {
- unsigned reg_to_write = reg;
- RegisterValue value_to_write = value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
- if (reg_info->invalidate_regs &&
- (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- if (ReadRegister(full_reg_info, full_value)) {
- Status error;
- ByteOrder byte_order = GetByteOrder();
- uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData(
- full_reg_info, dst, sizeof(dst), byte_order, error);
- if (error.Success() && dest_size) {
- uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = value.GetAsMemoryData(
- reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size)) {
- // Copy the src bytes to the destination.
- memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
- }
- }
-
- ProcessMonitor &monitor = GetMonitor();
-#if defined(__FreeBSD__)
- if (reg >= m_reg_info.first_dr)
- return monitor.WriteDebugRegisterValue(
- m_thread.GetID(), GetRegisterOffset(reg_to_write),
- GetRegisterName(reg_to_write), value_to_write);
-#endif
- return monitor.WriteRegisterValue(
- m_thread.GetID(), GetRegisterOffset(reg_to_write),
- GetRegisterName(reg_to_write), value_to_write);
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(
- const RegisterInfo *reg_info, RegisterValue &value) {
- if (!reg_info)
- return false;
-
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
- if (IsFPR(reg, GetFPRType())) {
- if (!ReadFPR())
- return false;
- } else {
- uint32_t full_reg = reg;
- bool is_subreg = reg_info->invalidate_regs &&
- (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
- if (is_subreg) {
- // Read the full aligned 64-bit register.
- full_reg = reg_info->invalidate_regs[0];
- }
-
- bool success = ReadRegister(full_reg, value);
-
- if (success) {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned
- // value one byte to the right.
- if (is_subreg && (reg_info->byte_offset & 0x1))
- value.SetUInt64(value.GetAsUInt64() >> 8);
-
- // If our return byte size was greater than the return value reg size,
- // then use the type specified by reg_info rather than the uint64_t
- // default
- if (value.GetByteSize() > reg_info->byte_size)
- value.SetType(reg_info);
- }
- return success;
- }
-
- if (reg_info->encoding == eEncodingVector) {
- ByteOrder byte_order = GetByteOrder();
-
- if (byte_order != ByteOrder::eByteOrderInvalid) {
- if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
- value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_st].bytes,
- reg_info->byte_size, byte_order);
- if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
- value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
- reg_info->byte_size, byte_order);
- if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
- value.SetBytes(m_fpr.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
- reg_info->byte_size, byte_order);
- if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
- // Concatenate ymm using the register halves in xmm.bytes and
- // ymmh.bytes
- if (GetFPRType() == eXSAVE && CopyXSTATEtoYMM(reg, byte_order))
- value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- reg_info->byte_size, byte_order);
- else
- return false;
- }
- return value.GetType() == RegisterValue::eTypeBytes;
- }
- return false;
- }
-
- // Get pointer to m_fpr.fxsave variable and set the data from it. Byte
- // offsets of all registers are calculated wrt 'UserArea' structure. However,
- // ReadFPR() reads fpu registers {using ptrace(PT_GETFPREGS,..)} and stores
- // them in 'm_fpr' (of type FPR structure). To extract values of fpu
- // registers, m_fpr should be read at byte offsets calculated wrt to FPR
- // structure.
-
- // Since, FPR structure is also one of the member of UserArea structure.
- // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
- // byte_offset(fctrl wrt UserArea)
- assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr));
- uint8_t *src =
- (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
- switch (reg_info->byte_size) {
- case 1:
- value.SetUInt8(*(uint8_t *)src);
- return true;
- case 2:
- value.SetUInt16(*(uint16_t *)src);
- return true;
- case 4:
- value.SetUInt32(*(uint32_t *)src);
- return true;
- case 8:
- value.SetUInt64(*(uint64_t *)src);
- return true;
- default:
- assert(false && "Unhandled data size.");
- return false;
- }
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(
- const RegisterInfo *reg_info, const RegisterValue &value) {
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
- if (IsGPR(reg))
- return WriteRegister(reg, value);
-
- if (IsFPR(reg, GetFPRType())) {
- if (reg_info->encoding == eEncodingVector) {
- if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
- ::memcpy(m_fpr.fxsave.stmm[reg - m_reg_info.first_st].bytes,
- value.GetBytes(), value.GetByteSize());
-
- if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
- ::memcpy(m_fpr.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
- value.GetBytes(), value.GetByteSize());
-
- if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
- ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
- value.GetBytes(), value.GetByteSize());
-
- if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
- if (GetFPRType() != eXSAVE)
- return false; // the target processor does not support AVX
-
- // Store ymm register content, and split into the register halves in
- // xmm.bytes and ymmh.bytes
- ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- value.GetBytes(), value.GetByteSize());
- if (false == CopyYMMtoXSTATE(reg, GetByteOrder()))
- return false;
- }
- } else {
- // Get pointer to m_fpr.fxsave variable and set the data to it. Byte
- // offsets of all registers are calculated wrt 'UserArea' structure.
- // However, WriteFPR() takes m_fpr (of type FPR structure) and writes
- // only fpu registers using ptrace(PT_SETFPREGS,..) API. Hence fpu
- // registers should be written in m_fpr at byte offsets calculated wrt
- // FPR structure.
-
- // Since, FPR structure is also one of the member of UserArea structure.
- // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
- // byte_offset(fctrl wrt UserArea)
- assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) <
- sizeof(m_fpr));
- uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset -
- m_fctrl_offset_in_userarea;
- switch (reg_info->byte_size) {
- case 1:
- *(uint8_t *)dst = value.GetAsUInt8();
- break;
- case 2:
- *(uint16_t *)dst = value.GetAsUInt16();
- break;
- case 4:
- *(uint32_t *)dst = value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return false;
- }
- }
-
- if (WriteFPR()) {
- if (IsAVX(reg))
- return CopyYMMtoXSTATE(reg, GetByteOrder());
- return true;
- }
- }
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::ReadAllRegisterValues(
- DataBufferSP &data_sp) {
- bool success = false;
- data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- if (ReadGPR() && ReadFPR()) {
- uint8_t *dst = data_sp->GetBytes();
- success = dst != 0;
-
- if (success) {
- ::memcpy(dst, &m_gpr_x86_64, GetGPRSize());
- dst += GetGPRSize();
- if (GetFPRType() == eFXSAVE)
- ::memcpy(dst, &m_fpr.fxsave, sizeof(m_fpr.fxsave));
- }
-
- if (GetFPRType() == eXSAVE) {
- ByteOrder byte_order = GetByteOrder();
-
- // Assemble the YMM register content from the register halves.
- for (uint32_t reg = m_reg_info.first_ymm;
- success && reg <= m_reg_info.last_ymm; ++reg)
- success = CopyXSTATEtoYMM(reg, byte_order);
-
- if (success) {
- // Copy the extended register state including the assembled ymm
- // registers.
- ::memcpy(dst, &m_fpr, sizeof(m_fpr));
- }
- }
- }
- return success;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::WriteAllRegisterValues(
- const DataBufferSP &data_sp) {
- bool success = false;
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
- uint8_t *src = data_sp->GetBytes();
- if (src) {
- ::memcpy(&m_gpr_x86_64, src, GetGPRSize());
-
- if (WriteGPR()) {
- src += GetGPRSize();
- if (GetFPRType() == eFXSAVE)
- ::memcpy(&m_fpr.fxsave, src, sizeof(m_fpr.fxsave));
- if (GetFPRType() == eXSAVE)
- ::memcpy(&m_fpr.xsave, src, sizeof(m_fpr.xsave));
-
- success = WriteFPR();
- if (success) {
- if (GetFPRType() == eXSAVE) {
- ByteOrder byte_order = GetByteOrder();
-
- // Parse the YMM register content from the register halves.
- for (uint32_t reg = m_reg_info.first_ymm;
- success && reg <= m_reg_info.last_ymm; ++reg)
- success = CopyYMMtoXSTATE(reg, byte_order);
- }
- }
- }
- }
- }
- return success;
-}
-
-uint32_t RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpoint(
- addr_t addr, size_t size, bool read, bool write) {
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- uint32_t hw_index;
-
- for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
- if (IsWatchpointVacant(hw_index))
- return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
- }
-
- return LLDB_INVALID_INDEX32;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::ClearHardwareWatchpoint(
- uint32_t hw_index) {
- if (hw_index < NumSupportedHardwareWatchpoints()) {
- RegisterValue current_dr7_bits;
-
- if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits)) {
- uint64_t new_dr7_bits =
- current_dr7_bits.GetAsUInt64() & ~(3 << (2 * hw_index));
-
- if (WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits)))
- return true;
- }
- }
-
- return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::HardwareSingleStep(
- bool enable) {
- enum { TRACE_BIT = 0x100 };
- uint64_t rflags;
-
- if ((rflags = ReadRegisterAsUnsigned(m_reg_info.gpr_flags, -1UL)) == -1UL)
- return false;
-
- if (enable) {
- if (rflags & TRACE_BIT)
- return true;
-
- rflags |= TRACE_BIT;
- } else {
- if (!(rflags & TRACE_BIT))
- return false;
-
- rflags &= ~TRACE_BIT;
- }
-
- return WriteRegisterFromUnsigned(m_reg_info.gpr_flags, rflags);
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::UpdateAfterBreakpoint() {
- // PC points one byte past the int3 responsible for the breakpoint.
- lldb::addr_t pc;
-
- if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
- return false;
-
- SetPC(pc - 1);
- return true;
-}
-
-unsigned RegisterContextPOSIXProcessMonitor_x86_64::GetRegisterIndexFromOffset(
- unsigned offset) {
- unsigned reg;
- for (reg = 0; reg < m_reg_info.num_registers; reg++) {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < m_reg_info.num_registers && "Invalid register offset.");
- return reg;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointHit(
- uint32_t hw_index) {
- bool is_hit = false;
-
- if (m_watchpoints_initialized == false) {
- // Reset the debug status and debug control registers
- RegisterValue zero_bits = RegisterValue(uint64_t(0));
- if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) ||
- !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
- assert(false && "Could not initialize watchpoint registers");
- m_watchpoints_initialized = true;
- }
-
- if (hw_index < NumSupportedHardwareWatchpoints()) {
- RegisterValue value;
-
- if (ReadRegister(m_reg_info.first_dr + 6, value)) {
- uint64_t val = value.GetAsUInt64();
- is_hit = val & (1 << hw_index);
- }
- }
-
- return is_hit;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::ClearWatchpointHits() {
- return WriteRegister(m_reg_info.first_dr + 6, RegisterValue((uint64_t)0));
-}
-
-addr_t RegisterContextPOSIXProcessMonitor_x86_64::GetWatchpointAddress(
- uint32_t hw_index) {
- addr_t wp_monitor_addr = LLDB_INVALID_ADDRESS;
-
- if (hw_index < NumSupportedHardwareWatchpoints()) {
- if (!IsWatchpointVacant(hw_index)) {
- RegisterValue value;
-
- if (ReadRegister(m_reg_info.first_dr + hw_index, value))
- wp_monitor_addr = value.GetAsUInt64();
- }
- }
-
- return wp_monitor_addr;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointVacant(
- uint32_t hw_index) {
- bool is_vacant = false;
- RegisterValue value;
-
- assert(hw_index < NumSupportedHardwareWatchpoints());
-
- if (m_watchpoints_initialized == false) {
- // Reset the debug status and debug control registers
- RegisterValue zero_bits = RegisterValue(uint64_t(0));
- if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) ||
- !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
- assert(false && "Could not initialize watchpoint registers");
- m_watchpoints_initialized = true;
- }
-
- if (ReadRegister(m_reg_info.first_dr + 7, value)) {
- uint64_t val = value.GetAsUInt64();
- is_vacant = (val & (3 << 2 * hw_index)) == 0;
- }
-
- return is_vacant;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpointWithIndex(
- addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
-
- if (num_hw_watchpoints == 0 || hw_index >= num_hw_watchpoints)
- return false;
-
- if (!(size == 1 || size == 2 || size == 4 || size == 8))
- return false;
-
- if (read == false && write == false)
- return false;
-
- if (!IsWatchpointVacant(hw_index))
- return false;
-
- // Set both dr7 (debug control register) and dri (debug address register).
-
- // dr7{7-0} encodes the local/global enable bits:
- // global enable --. .-- local enable
- // | |
- // v v
- // dr0 -> bits{1-0}
- // dr1 -> bits{3-2}
- // dr2 -> bits{5-4}
- // dr3 -> bits{7-6}
- //
- // dr7{31-16} encodes the rw/len bits:
- // b_x+3, b_x+2, b_x+1, b_x
- // where bits{x+1, x} => rw
- // 0b00: execute, 0b01: write, 0b11: read-or-write,
- // 0b10: io read-or-write (unused)
- // and bits{x+3, x+2} => len
- // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte
- //
- // dr0 -> bits{19-16}
- // dr1 -> bits{23-20}
- // dr2 -> bits{27-24}
- // dr3 -> bits{31-28}
- if (hw_index < num_hw_watchpoints) {
- RegisterValue current_dr7_bits;
-
- if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits)) {
- uint64_t new_dr7_bits =
- current_dr7_bits.GetAsUInt64() |
- (1 << (2 * hw_index) |
- size_and_rw_bits(size, read, write) << (16 + 4 * hw_index));
-
- if (WriteRegister(m_reg_info.first_dr + hw_index, RegisterValue(addr)) &&
- WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits)))
- return true;
- }
- }
-
- return false;
-}
-
-uint32_t
-RegisterContextPOSIXProcessMonitor_x86_64::NumSupportedHardwareWatchpoints() {
- // Available debug address registers: dr0, dr1, dr2, dr3
- return 4;
-}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h
deleted file mode 100644
index c9dc02a88e01..000000000000
--- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h
+++ /dev/null
@@ -1,81 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_x86.h ----------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextPOSIXProcessMonitor_x86_H_
-#define liblldb_RegisterContextPOSIXProcessMonitor_x86_H_
-
-#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
-#include "RegisterContextPOSIX.h"
-#include <sys/uio.h>
-
-class RegisterContextPOSIXProcessMonitor_x86_64
- : public RegisterContextPOSIX_x86,
- public POSIXBreakpointProtocol {
-public:
- RegisterContextPOSIXProcessMonitor_x86_64(
- lldb_private::Thread &thread, uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
-
-protected:
- bool ReadGPR();
-
- bool ReadFPR();
-
- bool WriteGPR();
-
- bool WriteFPR();
-
- // lldb_private::RegisterContext
- bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
-
- bool WriteRegister(const unsigned reg,
- const lldb_private::RegisterValue &value);
-
- bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value);
-
- bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value);
-
- bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
-
- bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
-
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
- bool write);
-
- bool ClearHardwareWatchpoint(uint32_t hw_index);
-
- bool HardwareSingleStep(bool enable);
-
- // POSIXBreakpointProtocol
- bool UpdateAfterBreakpoint();
-
- unsigned GetRegisterIndexFromOffset(unsigned offset);
-
- bool IsWatchpointHit(uint32_t hw_index);
-
- bool ClearWatchpointHits();
-
- lldb::addr_t GetWatchpointAddress(uint32_t hw_index);
-
- bool IsWatchpointVacant(uint32_t hw_index);
-
- bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
- bool write, uint32_t hw_index);
-
- uint32_t NumSupportedHardwareWatchpoints();
-
-private:
- ProcessMonitor &GetMonitor();
- uint32_t
- m_fctrl_offset_in_userarea; // Offset of 'fctrl' in 'UserArea' Structure
- struct iovec m_iovec;
-};
-
-#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 5109022d80dd..57f0eb3cceb6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -98,18 +98,7 @@ NativeProcessNetBSD::Factory::Launch(ProcessLaunchInfo &launch_info,
pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate,
Info.GetArchitecture(), mainloop));
- // Enable event reporting
- ptrace_event_t events;
- status = PtraceWrapper(PT_GET_EVENT_MASK, pid, &events, sizeof(events));
- if (status.Fail())
- return status.ToError();
- // TODO: PTRACE_FORK | PTRACE_VFORK | PTRACE_POSIX_SPAWN?
- events.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT;
- status = PtraceWrapper(PT_SET_EVENT_MASK, pid, &events, sizeof(events));
- if (status.Fail())
- return status.ToError();
-
- status = process_up->ReinitializeThreads();
+ status = process_up->SetupTrace();
if (status.Fail())
return status.ToError();
@@ -218,10 +207,14 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
// Get details on the signal raised.
if (siginfo_err.Fail()) {
+ LLDB_LOG(log, "PT_GET_SIGINFO failed {0}", siginfo_err);
return;
}
- NativeThreadNetBSD* thread = nullptr;
+ LLDB_LOG(log, "got SIGTRAP, pid = {0}, lwpid = {1}, si_code = {2}", pid,
+ info.psi_lwpid, info.psi_siginfo.si_code);
+ NativeThreadNetBSD *thread = nullptr;
+
if (info.psi_lwpid > 0) {
for (const auto &t : m_threads) {
if (t->GetID() == static_cast<lldb::tid_t>(info.psi_lwpid)) {
@@ -231,8 +224,7 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
static_cast<NativeThreadNetBSD *>(t.get())->SetStoppedWithNoReason();
}
if (!thread)
- LLDB_LOG(log,
- "thread not found in m_threads, pid = {0}, LWP = {1}", pid,
+ LLDB_LOG(log, "thread not found in m_threads, pid = {0}, LWP = {1}", pid,
info.psi_lwpid);
}
@@ -243,12 +235,12 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
FixupBreakpointPCAsNeeded(*thread);
}
SetState(StateType::eStateStopped, true);
- break;
+ return;
case TRAP_TRACE:
if (thread)
thread->SetStoppedByTrace();
SetState(StateType::eStateStopped, true);
- break;
+ return;
case TRAP_EXEC: {
Status error = ReinitializeThreads();
if (error.Fail()) {
@@ -262,7 +254,8 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
for (const auto &thread : m_threads)
static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByExec();
SetState(StateType::eStateStopped, true);
- } break;
+ return;
+ }
case TRAP_LWP: {
ptrace_state_t pst;
Status error = PtraceWrapper(PT_GET_PROCESS_STATE, pid, &pst, sizeof(pst));
@@ -272,35 +265,31 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
}
switch (pst.pe_report_event) {
- case PTRACE_LWP_CREATE: {
- LLDB_LOG(log,
- "monitoring new thread, pid = {0}, LWP = {1}", pid,
- pst.pe_lwp);
- NativeThreadNetBSD& t = AddThread(pst.pe_lwp);
- error = t.CopyWatchpointsFrom(
- static_cast<NativeThreadNetBSD &>(*GetCurrentThread()));
- if (error.Fail()) {
- LLDB_LOG(log,
- "failed to copy watchpoints to new thread {0}: {1}",
- pst.pe_lwp, error);
- SetState(StateType::eStateInvalid);
- return;
- }
- } break;
- case PTRACE_LWP_EXIT:
- LLDB_LOG(log,
- "removing exited thread, pid = {0}, LWP = {1}", pid,
- pst.pe_lwp);
- RemoveThread(pst.pe_lwp);
- break;
+ case PTRACE_LWP_CREATE: {
+ LLDB_LOG(log, "monitoring new thread, pid = {0}, LWP = {1}", pid,
+ pst.pe_lwp);
+ NativeThreadNetBSD &t = AddThread(pst.pe_lwp);
+ error = t.CopyWatchpointsFrom(
+ static_cast<NativeThreadNetBSD &>(*GetCurrentThread()));
+ if (error.Fail()) {
+ LLDB_LOG(log, "failed to copy watchpoints to new thread {0}: {1}",
+ pst.pe_lwp, error);
+ SetState(StateType::eStateInvalid);
+ return;
+ }
+ } break;
+ case PTRACE_LWP_EXIT:
+ LLDB_LOG(log, "removing exited thread, pid = {0}, LWP = {1}", pid,
+ pst.pe_lwp);
+ RemoveThread(pst.pe_lwp);
+ break;
}
- error = PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void*>(1), 0);
- if (error.Fail()) {
+ error = PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0);
+ if (error.Fail())
SetState(StateType::eStateInvalid);
- return;
- }
- } break;
+ return;
+ }
case TRAP_DBREG: {
if (!thread)
break;
@@ -308,29 +297,42 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
auto &regctx = static_cast<NativeRegisterContextNetBSD &>(
thread->GetRegisterContext());
uint32_t wp_index = LLDB_INVALID_INDEX32;
- Status error = regctx.GetWatchpointHitIndex(wp_index,
- (uintptr_t)info.psi_siginfo.si_addr);
+ Status error = regctx.GetWatchpointHitIndex(
+ wp_index, (uintptr_t)info.psi_siginfo.si_addr);
if (error.Fail())
LLDB_LOG(log,
"received error while checking for watchpoint hits, pid = "
- "{0}, LWP = {1}, error = {2}", pid, info.psi_lwpid, error);
+ "{0}, LWP = {1}, error = {2}",
+ pid, info.psi_lwpid, error);
if (wp_index != LLDB_INVALID_INDEX32) {
thread->SetStoppedByWatchpoint(wp_index);
regctx.ClearWatchpointHit(wp_index);
SetState(StateType::eStateStopped, true);
- break;
+ return;
}
thread->SetStoppedByTrace();
SetState(StateType::eStateStopped, true);
- } break;
+ return;
}
+ }
+
+ // Either user-generated SIGTRAP or an unknown event that would
+ // otherwise leave the debugger hanging.
+ LLDB_LOG(log, "unknown SIGTRAP, passing to generic handler");
+ MonitorSignal(pid, SIGTRAP);
}
void NativeProcessNetBSD::MonitorSignal(lldb::pid_t pid, int signal) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
ptrace_siginfo_t info;
+
const auto siginfo_err =
PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info));
+ if (siginfo_err.Fail()) {
+ LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err);
+ return;
+ }
for (const auto &abs_thread : m_threads) {
NativeThreadNetBSD &thread = static_cast<NativeThreadNetBSD &>(*abs_thread);
@@ -489,16 +491,14 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
signal = siginfo->psi_siginfo.si_signo;
}
- ret = PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1),
- signal);
+ ret =
+ PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), signal);
if (ret.Success())
SetState(eStateRunning, true);
return ret;
}
-Status NativeProcessNetBSD::Halt() {
- return PtraceWrapper(PT_STOP, GetID());
-}
+Status NativeProcessNetBSD::Halt() { return PtraceWrapper(PT_STOP, GetID()); }
Status NativeProcessNetBSD::Detach() {
Status error;
@@ -662,8 +662,8 @@ Status NativeProcessNetBSD::PopulateMemoryRegionCache() {
if (vm[i].kve_path[0])
info.SetName(vm[i].kve_path);
- m_mem_region_cache.emplace_back(
- info, FileSpec(info.GetName().GetCString()));
+ m_mem_region_cache.emplace_back(info,
+ FileSpec(info.GetName().GetCString()));
}
free(vm);
@@ -684,15 +684,6 @@ Status NativeProcessNetBSD::PopulateMemoryRegionCache() {
return Status();
}
-Status NativeProcessNetBSD::AllocateMemory(size_t size, uint32_t permissions,
- lldb::addr_t &addr) {
- return Status("Unimplemented");
-}
-
-Status NativeProcessNetBSD::DeallocateMemory(lldb::addr_t addr) {
- return Status("Unimplemented");
-}
-
lldb::addr_t NativeProcessNetBSD::GetSharedLibraryInfoAddress() {
// punt on this for now
return LLDB_INVALID_ADDRESS;
@@ -710,21 +701,47 @@ Status NativeProcessNetBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size,
Status NativeProcessNetBSD::GetLoadedModuleFileSpec(const char *module_path,
FileSpec &file_spec) {
- return Status("Unimplemented");
+ Status error = PopulateMemoryRegionCache();
+ if (error.Fail())
+ return error;
+
+ FileSpec module_file_spec(module_path);
+ FileSystem::Instance().Resolve(module_file_spec);
+
+ file_spec.Clear();
+ for (const auto &it : m_mem_region_cache) {
+ if (it.second.GetFilename() == module_file_spec.GetFilename()) {
+ file_spec = it.second;
+ return Status();
+ }
+ }
+ return Status("Module file (%s) not found in process' memory map!",
+ module_file_spec.GetFilename().AsCString());
}
Status NativeProcessNetBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
lldb::addr_t &load_addr) {
load_addr = LLDB_INVALID_ADDRESS;
- return Status();
+ Status error = PopulateMemoryRegionCache();
+ if (error.Fail())
+ return error;
+
+ FileSpec file(file_name);
+ for (const auto &it : m_mem_region_cache) {
+ if (it.second == file) {
+ load_addr = it.first.GetRange().GetRangeBase();
+ return Status();
+ }
+ }
+ return Status("No load address found for file %s.", file_name.str().c_str());
}
void NativeProcessNetBSD::SigchldHandler() {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
// Process all pending waitpid notifications.
int status;
- ::pid_t wait_pid =
- llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status, WALLSIG | WNOHANG);
+ ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status,
+ WALLSIG | WNOHANG);
if (wait_pid == 0)
return; // We are done.
@@ -806,12 +823,13 @@ Status NativeProcessNetBSD::Attach() {
int wstatus;
// Need to use WALLSIG otherwise we receive an error with errno=ECHLD At this
// point we should have a thread stopped if waitpid succeeds.
- if ((wstatus = llvm::sys::RetryAfterSignal(-1, waitpid,
- m_pid, nullptr, WALLSIG)) < 0)
+ if ((wstatus = llvm::sys::RetryAfterSignal(-1, waitpid, m_pid, nullptr,
+ WALLSIG)) < 0)
return Status(errno, eErrorTypePOSIX);
- /* Initialize threads */
- status = ReinitializeThreads();
+ // Initialize threads and tracing status
+ // NB: this needs to be called before we set thread state
+ status = SetupTrace();
if (status.Fail())
return status;
@@ -819,7 +837,8 @@ Status NativeProcessNetBSD::Attach() {
static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
// Let our process instance know the thread has stopped.
- SetState(StateType::eStateStopped);
+ SetCurrentThreadID(m_threads.front()->GetID());
+ SetState(StateType::eStateStopped, false);
return Status();
}
@@ -864,7 +883,8 @@ Status NativeProcessNetBSD::WriteMemory(lldb::addr_t addr, const void *buf,
io.piod_len = size;
do {
- io.piod_addr = const_cast<void *>(static_cast<const void *>(src + bytes_written));
+ io.piod_addr =
+ const_cast<void *>(static_cast<const void *>(src + bytes_written));
io.piod_offs = (void *)(addr + bytes_written);
Status error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io);
@@ -909,6 +929,22 @@ NativeProcessNetBSD::GetAuxvData() const {
return std::move(buf);
}
+Status NativeProcessNetBSD::SetupTrace() {
+ // Enable event reporting
+ ptrace_event_t events;
+ Status status =
+ PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events));
+ if (status.Fail())
+ return status;
+ // TODO: PTRACE_FORK | PTRACE_VFORK | PTRACE_POSIX_SPAWN?
+ events.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT;
+ status = PtraceWrapper(PT_SET_EVENT_MASK, GetID(), &events, sizeof(events));
+ if (status.Fail())
+ return status;
+
+ return ReinitializeThreads();
+}
+
Status NativeProcessNetBSD::ReinitializeThreads() {
// Clear old threads
m_threads.clear();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
index 6a06773f40a8..3d59a4f72e94 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
@@ -60,11 +60,6 @@ public:
Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
size_t &bytes_written) override;
- Status AllocateMemory(size_t size, uint32_t permissions,
- lldb::addr_t &addr) override;
-
- Status DeallocateMemory(lldb::addr_t addr) override;
-
lldb::addr_t GetSharedLibraryInfoAddress() override;
size_t UpdateThreads() override;
@@ -74,9 +69,13 @@ public:
Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
bool hardware) override;
+ // The two following methods are probably not necessary and probably
+ // will never be called. Nevertheless, we implement them right now
+ // to reduce the differences between different platforms and reduce
+ // the risk of the lack of implementation actually breaking something,
+ // at least for the time being.
Status GetLoadedModuleFileSpec(const char *module_path,
FileSpec &file_spec) override;
-
Status GetFileLoadAddress(const llvm::StringRef &file_name,
lldb::addr_t &load_addr) override;
@@ -112,6 +111,7 @@ private:
void SigchldHandler();
Status Attach();
+ Status SetupTrace();
Status ReinitializeThreads();
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
index 03b505c19890..4755dab0b073 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
@@ -20,12 +20,6 @@ using namespace lldb_private::process_netbsd;
#include <sys/ptrace.h>
// clang-format on
-NativeRegisterContextNetBSD::NativeRegisterContextNetBSD(
- NativeThreadProtocol &native_thread,
- RegisterInfoInterface *reg_info_interface_p)
- : NativeRegisterContextRegisterInfo(native_thread,
- reg_info_interface_p) {}
-
Status NativeRegisterContextNetBSD::DoRegisterSet(int ptrace_req, void *buf) {
return NativeProcessNetBSD::PtraceWrapper(ptrace_req, GetProcessPid(), buf,
m_thread.GetID());
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
index 13e023d856d2..08490aad9e0b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
@@ -18,11 +18,9 @@ namespace process_netbsd {
class NativeProcessNetBSD;
-class NativeRegisterContextNetBSD : public NativeRegisterContextRegisterInfo {
+class NativeRegisterContextNetBSD
+ : public virtual NativeRegisterContextRegisterInfo {
public:
- NativeRegisterContextNetBSD(NativeThreadProtocol &native_thread,
- RegisterInfoInterface *reg_info_interface_p);
-
// This function is implemented in the NativeRegisterContextNetBSD_*
// subclasses to create a new instance of the host specific
// NativeRegisterContextNetBSD. The implementations can't collide as only one
@@ -31,11 +29,9 @@ public:
static NativeRegisterContextNetBSD *
CreateHostNativeRegisterContextNetBSD(const ArchSpec &target_arch,
NativeThreadProtocol &native_thread);
- virtual Status
+ virtual llvm::Error
CopyHardwareWatchpointsFrom(NativeRegisterContextNetBSD &source) = 0;
- virtual Status ClearWatchpointHit(uint32_t wp_index) = 0;
-
protected:
Status DoRegisterSet(int req, void *buf);
virtual NativeProcessNetBSD &GetProcess();
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
index ca4706a65657..ed1884c94a4b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
@@ -36,9 +36,6 @@
using namespace lldb_private;
using namespace lldb_private::process_netbsd;
-// Private namespace.
-
-namespace {
// x86 64-bit general purpose registers.
static const uint32_t g_gpr_regnums_x86_64[] = {
lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64,
@@ -87,20 +84,21 @@ static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
// x86 64-bit floating point registers.
static const uint32_t g_fpu_regnums_x86_64[] = {
- lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64,
- lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64,
- lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_mxcsr_x86_64,
- lldb_mxcsrmask_x86_64, lldb_st0_x86_64, lldb_st1_x86_64,
- lldb_st2_x86_64, lldb_st3_x86_64, lldb_st4_x86_64,
- lldb_st5_x86_64, lldb_st6_x86_64, lldb_st7_x86_64,
- lldb_mm0_x86_64, lldb_mm1_x86_64, lldb_mm2_x86_64,
- lldb_mm3_x86_64, lldb_mm4_x86_64, lldb_mm5_x86_64,
- lldb_mm6_x86_64, lldb_mm7_x86_64, lldb_xmm0_x86_64,
- lldb_xmm1_x86_64, lldb_xmm2_x86_64, lldb_xmm3_x86_64,
- lldb_xmm4_x86_64, lldb_xmm5_x86_64, lldb_xmm6_x86_64,
- lldb_xmm7_x86_64, lldb_xmm8_x86_64, lldb_xmm9_x86_64,
- lldb_xmm10_x86_64, lldb_xmm11_x86_64, lldb_xmm12_x86_64,
- lldb_xmm13_x86_64, lldb_xmm14_x86_64, lldb_xmm15_x86_64,
+ lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64,
+ lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64,
+ lldb_fip_x86_64, lldb_foseg_x86_64, lldb_fooff_x86_64,
+ lldb_fdp_x86_64, lldb_mxcsr_x86_64, lldb_mxcsrmask_x86_64,
+ lldb_st0_x86_64, lldb_st1_x86_64, lldb_st2_x86_64,
+ lldb_st3_x86_64, lldb_st4_x86_64, lldb_st5_x86_64,
+ lldb_st6_x86_64, lldb_st7_x86_64, lldb_mm0_x86_64,
+ lldb_mm1_x86_64, lldb_mm2_x86_64, lldb_mm3_x86_64,
+ lldb_mm4_x86_64, lldb_mm5_x86_64, lldb_mm6_x86_64,
+ lldb_mm7_x86_64, lldb_xmm0_x86_64, lldb_xmm1_x86_64,
+ lldb_xmm2_x86_64, lldb_xmm3_x86_64, lldb_xmm4_x86_64,
+ lldb_xmm5_x86_64, lldb_xmm6_x86_64, lldb_xmm7_x86_64,
+ lldb_xmm8_x86_64, lldb_xmm9_x86_64, lldb_xmm10_x86_64,
+ lldb_xmm11_x86_64, lldb_xmm12_x86_64, lldb_xmm13_x86_64,
+ lldb_xmm14_x86_64, lldb_xmm15_x86_64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) -
@@ -108,27 +106,34 @@ static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) -
k_num_fpr_registers_x86_64,
"g_fpu_regnums_x86_64 has wrong number of register infos");
-// x86 64-bit registers available via XState.
-static const uint32_t g_xstate_regnums_x86_64[] = {
+static const uint32_t g_avx_regnums_x86_64[] = {
lldb_ymm0_x86_64, lldb_ymm1_x86_64, lldb_ymm2_x86_64, lldb_ymm3_x86_64,
lldb_ymm4_x86_64, lldb_ymm5_x86_64, lldb_ymm6_x86_64, lldb_ymm7_x86_64,
lldb_ymm8_x86_64, lldb_ymm9_x86_64, lldb_ymm10_x86_64, lldb_ymm11_x86_64,
lldb_ymm12_x86_64, lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -
+ 1 ==
+ k_num_avx_registers_x86_64,
+ "g_avx_regnums_x86_64 has wrong number of register infos");
+
+static const uint32_t g_mpx_regnums_x86_64[] = {
// Note: we currently do not provide them but this is needed to avoid
// unnamed groups in SBFrame::GetRegisterContext().
- lldb_bnd0_x86_64, lldb_bnd1_x86_64, lldb_bnd2_x86_64,
- lldb_bnd3_x86_64, lldb_bndcfgu_x86_64, lldb_bndstatus_x86_64,
+ lldb_bnd0_x86_64, lldb_bnd1_x86_64, lldb_bnd2_x86_64,
+ lldb_bnd3_x86_64, lldb_bndcfgu_x86_64, lldb_bndstatus_x86_64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert((sizeof(g_xstate_regnums_x86_64) / sizeof(g_xstate_regnums_x86_64[0])) -
+static_assert((sizeof(g_mpx_regnums_x86_64) / sizeof(g_mpx_regnums_x86_64[0])) -
1 ==
- k_num_avx_registers_x86_64 + k_num_mpx_registers_x86_64,
- "g_xstate_regnums_x86_64 has wrong number of register infos");
+ k_num_mpx_registers_x86_64,
+ "g_mpx_regnums_x86_64 has wrong number of register infos");
// x86 debug registers.
static const uint32_t g_dbr_regnums_x86_64[] = {
- lldb_dr0_x86_64, lldb_dr1_x86_64, lldb_dr2_x86_64, lldb_dr3_x86_64,
- lldb_dr4_x86_64, lldb_dr5_x86_64, lldb_dr6_x86_64, lldb_dr7_x86_64,
+ lldb_dr0_x86_64, lldb_dr1_x86_64, lldb_dr2_x86_64, lldb_dr3_x86_64,
+ lldb_dr4_x86_64, lldb_dr5_x86_64, lldb_dr6_x86_64, lldb_dr7_x86_64,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_dbr_regnums_x86_64) / sizeof(g_dbr_regnums_x86_64[0])) -
@@ -137,7 +142,7 @@ static_assert((sizeof(g_dbr_regnums_x86_64) / sizeof(g_dbr_regnums_x86_64[0])) -
"g_dbr_regnums_x86_64 has wrong number of register infos");
// x86 32-bit general purpose registers.
-const uint32_t g_gpr_regnums_i386[] = {
+static const uint32_t g_gpr_regnums_i386[] = {
lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386,
lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386,
lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386,
@@ -154,7 +159,7 @@ static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
"g_gpr_regnums_i386 has wrong number of register infos");
// x86 32-bit floating point registers.
-const uint32_t g_fpu_regnums_i386[] = {
+static const uint32_t g_fpu_regnums_i386[] = {
lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386,
lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386,
lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386,
@@ -171,25 +176,32 @@ static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) -
k_num_fpr_registers_i386,
"g_fpu_regnums_i386 has wrong number of register infos");
-// x86 64-bit registers available via XState.
-static const uint32_t g_xstate_regnums_i386[] = {
- lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
- lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
+static const uint32_t g_avx_regnums_i386[] = {
+ lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
+ lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -
+ 1 ==
+ k_num_avx_registers_i386,
+ "g_avx_regnums_i386 has wrong number of register infos");
+
+static const uint32_t g_mpx_regnums_i386[] = {
// Note: we currently do not provide them but this is needed to avoid
// unnamed groups in SBFrame::GetRegisterContext().
- lldb_bnd0_i386, lldb_bnd1_i386, lldb_bnd2_i386,
- lldb_bnd3_i386, lldb_bndcfgu_i386, lldb_bndstatus_i386,
+ lldb_bnd0_i386, lldb_bnd1_i386, lldb_bnd2_i386,
+ lldb_bnd3_i386, lldb_bndcfgu_i386, lldb_bndstatus_i386,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
-static_assert((sizeof(g_xstate_regnums_i386) / sizeof(g_xstate_regnums_i386[0])) -
+static_assert((sizeof(g_mpx_regnums_i386) / sizeof(g_mpx_regnums_i386[0])) -
1 ==
- k_num_avx_registers_i386 + k_num_mpx_registers_i386,
- "g_xstate_regnums_i386 has wrong number of register infos");
+ k_num_mpx_registers_i386,
+ "g_mpx_regnums_i386 has wrong number of register infos");
// x86 debug registers.
static const uint32_t g_dbr_regnums_i386[] = {
- lldb_dr0_i386, lldb_dr1_i386, lldb_dr2_i386, lldb_dr3_i386,
- lldb_dr4_i386, lldb_dr5_i386, lldb_dr6_i386, lldb_dr7_i386,
+ lldb_dr0_i386, lldb_dr1_i386, lldb_dr2_i386, lldb_dr3_i386,
+ lldb_dr4_i386, lldb_dr5_i386, lldb_dr6_i386, lldb_dr7_i386,
LLDB_INVALID_REGNUM // register sets need to end with this flag
};
static_assert((sizeof(g_dbr_regnums_i386) / sizeof(g_dbr_regnums_i386[0])) -
@@ -197,9 +209,8 @@ static_assert((sizeof(g_dbr_regnums_i386) / sizeof(g_dbr_regnums_i386[0])) -
k_num_dbr_registers_i386,
"g_dbr_regnums_i386 has wrong number of register infos");
-
// Number of register sets provided by this context.
-enum { k_num_register_sets = 4 };
+enum { k_num_register_sets = 5 };
// Register sets for x86 32-bit.
static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
@@ -207,11 +218,11 @@ static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
g_gpr_regnums_i386},
{"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
g_fpu_regnums_i386},
- {"Extended State Registers", "xstate",
- k_num_avx_registers_i386 + k_num_mpx_registers_i386,
- g_xstate_regnums_i386},
- {"Debug Registers", "dbr", k_num_dbr_registers_i386,
- g_dbr_regnums_i386},
+ {"Debug Registers", "dbr", k_num_dbr_registers_i386, g_dbr_regnums_i386},
+ {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
+ g_avx_regnums_i386},
+ {"Memory Protection Extensions", "mpx", k_num_mpx_registers_i386,
+ g_mpx_regnums_i386},
};
// Register sets for x86 64-bit.
@@ -220,15 +231,15 @@ static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
g_gpr_regnums_x86_64},
{"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64,
g_fpu_regnums_x86_64},
- {"Extended State Registers", "xstate",
- k_num_avx_registers_x86_64 + k_num_mpx_registers_x86_64,
- g_xstate_regnums_x86_64},
{"Debug Registers", "dbr", k_num_dbr_registers_x86_64,
g_dbr_regnums_x86_64},
+ {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64,
+ g_avx_regnums_x86_64},
+ {"Memory Protection Extensions", "mpx", k_num_mpx_registers_x86_64,
+ g_mpx_regnums_x86_64},
};
#define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize())
-} // namespace
NativeRegisterContextNetBSD *
NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD(
@@ -246,28 +257,41 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) {
} else {
assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
"Register setting path assumes this is a 64-bit host");
- // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64
- // register context.
+ // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the
+ // x86_64 register context.
return new RegisterContextNetBSD_x86_64(target_arch);
}
}
NativeRegisterContextNetBSD_x86_64::NativeRegisterContextNetBSD_x86_64(
const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextNetBSD(native_thread,
- CreateRegisterInfoInterface(target_arch)),
- m_gpr(), m_fpr(), m_dbr() {}
+ : NativeRegisterContextRegisterInfo(
+ native_thread, CreateRegisterInfoInterface(target_arch)),
+ m_regset_offsets({0}) {
+ assert(m_gpr.size() == GetRegisterInfoInterface().GetGPRSize());
+ std::array<uint32_t, MaxRegularRegSet + 1> first_regnos;
-// CONSIDER after local and llgs debugging are merged, register set support can
-// be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
-uint32_t NativeRegisterContextNetBSD_x86_64::GetRegisterSetCount() const {
- uint32_t sets = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
- if (GetSetForNativeRegNum(set_index) != -1)
- ++sets;
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::x86:
+ first_regnos[FPRegSet] = lldb_fctrl_i386;
+ first_regnos[DBRegSet] = lldb_dr0_i386;
+ break;
+ case llvm::Triple::x86_64:
+ first_regnos[FPRegSet] = lldb_fctrl_x86_64;
+ first_regnos[DBRegSet] = lldb_dr0_x86_64;
+ break;
+ default:
+ llvm_unreachable("Unhandled target architecture.");
}
- return sets;
+ for (int i : {FPRegSet, DBRegSet})
+ m_regset_offsets[i] = GetRegisterInfoInterface()
+ .GetRegisterInfo()[first_regnos[i]]
+ .byte_offset;
+}
+
+uint32_t NativeRegisterContextNetBSD_x86_64::GetRegisterSetCount() const {
+ return k_num_register_sets;
}
const RegisterSet *
@@ -278,199 +302,79 @@ NativeRegisterContextNetBSD_x86_64::GetRegisterSet(uint32_t set_index) const {
case llvm::Triple::x86_64:
return &g_reg_sets_x86_64[set_index];
default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
+ llvm_unreachable("Unhandled target architecture.");
}
-
- return nullptr;
}
-static constexpr int RegNumX86ToX86_64(int regnum) {
- switch (regnum) {
- case lldb_eax_i386:
- return lldb_rax_x86_64;
- case lldb_ebx_i386:
- return lldb_rbx_x86_64;
- case lldb_ecx_i386:
- return lldb_rcx_x86_64;
- case lldb_edx_i386:
- return lldb_rdx_x86_64;
- case lldb_edi_i386:
- return lldb_rdi_x86_64;
- case lldb_esi_i386:
- return lldb_rsi_x86_64;
- case lldb_ebp_i386:
- return lldb_rbp_x86_64;
- case lldb_esp_i386:
- return lldb_rsp_x86_64;
- case lldb_eip_i386:
- return lldb_rip_x86_64;
- case lldb_eflags_i386:
- return lldb_rflags_x86_64;
- case lldb_cs_i386:
- return lldb_cs_x86_64;
- case lldb_fs_i386:
- return lldb_fs_x86_64;
- case lldb_gs_i386:
- return lldb_gs_x86_64;
- case lldb_ss_i386:
- return lldb_ss_x86_64;
- case lldb_ds_i386:
- return lldb_ds_x86_64;
- case lldb_es_i386:
- return lldb_es_x86_64;
- case lldb_fctrl_i386:
- return lldb_fctrl_x86_64;
- case lldb_fstat_i386:
- return lldb_fstat_x86_64;
- case lldb_ftag_i386:
- return lldb_fstat_x86_64;
- case lldb_fop_i386:
- return lldb_fop_x86_64;
- case lldb_fiseg_i386:
- return lldb_fiseg_x86_64;
- case lldb_fioff_i386:
- return lldb_fioff_x86_64;
- case lldb_foseg_i386:
- return lldb_foseg_x86_64;
- case lldb_fooff_i386:
- return lldb_fooff_x86_64;
- case lldb_mxcsr_i386:
- return lldb_mxcsr_x86_64;
- case lldb_mxcsrmask_i386:
- return lldb_mxcsrmask_x86_64;
- case lldb_st0_i386:
- case lldb_st1_i386:
- case lldb_st2_i386:
- case lldb_st3_i386:
- case lldb_st4_i386:
- case lldb_st5_i386:
- case lldb_st6_i386:
- case lldb_st7_i386:
- return lldb_st0_x86_64 + regnum - lldb_st0_i386;
- case lldb_mm0_i386:
- case lldb_mm1_i386:
- case lldb_mm2_i386:
- case lldb_mm3_i386:
- case lldb_mm4_i386:
- case lldb_mm5_i386:
- case lldb_mm6_i386:
- case lldb_mm7_i386:
- return lldb_mm0_x86_64 + regnum - lldb_mm0_i386;
- case lldb_xmm0_i386:
- case lldb_xmm1_i386:
- case lldb_xmm2_i386:
- case lldb_xmm3_i386:
- case lldb_xmm4_i386:
- case lldb_xmm5_i386:
- case lldb_xmm6_i386:
- case lldb_xmm7_i386:
- return lldb_xmm0_x86_64 + regnum - lldb_xmm0_i386;
- case lldb_ymm0_i386:
- case lldb_ymm1_i386:
- case lldb_ymm2_i386:
- case lldb_ymm3_i386:
- case lldb_ymm4_i386:
- case lldb_ymm5_i386:
- case lldb_ymm6_i386:
- case lldb_ymm7_i386:
- return lldb_ymm0_x86_64 + regnum - lldb_ymm0_i386;
- case lldb_dr0_i386:
- case lldb_dr1_i386:
- case lldb_dr2_i386:
- case lldb_dr3_i386:
- case lldb_dr4_i386:
- case lldb_dr5_i386:
- case lldb_dr6_i386:
- case lldb_dr7_i386:
- return lldb_dr0_x86_64 + regnum - lldb_dr0_i386;
- default:
- assert(false && "Unhandled i386 register.");
- return 0;
- }
-}
-
-int NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum(
- int reg_num) const {
+llvm::Optional<NativeRegisterContextNetBSD_x86_64::RegSetKind>
+NativeRegisterContextNetBSD_x86_64::GetSetForNativeRegNum(
+ uint32_t reg_num) const {
switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
case llvm::Triple::x86:
- if (reg_num <= k_last_gpr_i386)
+ if (reg_num >= k_first_gpr_i386 && reg_num <= k_last_gpr_i386)
return GPRegSet;
- else if (reg_num <= k_last_fpr_i386)
+ if (reg_num >= k_first_fpr_i386 && reg_num <= k_last_fpr_i386)
return FPRegSet;
- else if (reg_num <= k_last_avx_i386)
- return XStateRegSet; // AVX
- else if (reg_num <= lldb_dr7_i386)
+ if (reg_num >= k_first_avx_i386 && reg_num <= k_last_avx_i386)
+ return YMMRegSet;
+ if (reg_num >= k_first_mpxr_i386 && reg_num <= k_last_mpxr_i386)
+ return llvm::None; // MPXR
+ if (reg_num >= k_first_mpxc_i386 && reg_num <= k_last_mpxc_i386)
+ return llvm::None; // MPXC
+ if (reg_num >= k_first_dbr_i386 && reg_num <= k_last_dbr_i386)
return DBRegSet; // DBR
- else
- return -1;
+ break;
case llvm::Triple::x86_64:
- if (reg_num <= k_last_gpr_x86_64)
+ if (reg_num >= k_first_gpr_x86_64 && reg_num <= k_last_gpr_x86_64)
return GPRegSet;
- else if (reg_num <= k_last_fpr_x86_64)
+ if (reg_num >= k_first_fpr_x86_64 && reg_num <= k_last_fpr_x86_64)
return FPRegSet;
- else if (reg_num <= k_last_avx_x86_64)
- return XStateRegSet; // AVX
- else if (reg_num <= k_last_mpxr_x86_64)
- return -1; // MPXR
- else if (reg_num <= k_last_mpxc_x86_64)
- return -1; // MPXC
- else if (reg_num <= lldb_dr7_x86_64)
+ if (reg_num >= k_first_avx_x86_64 && reg_num <= k_last_avx_x86_64)
+ return YMMRegSet;
+ if (reg_num >= k_first_mpxr_x86_64 && reg_num <= k_last_mpxr_x86_64)
+ return llvm::None; // MPXR
+ if (reg_num >= k_first_mpxc_x86_64 && reg_num <= k_last_mpxc_x86_64)
+ return llvm::None; // MPXC
+ if (reg_num >= k_first_dbr_x86_64 && reg_num <= k_last_dbr_x86_64)
return DBRegSet; // DBR
- else
- return -1;
+ break;
default:
- assert(false && "Unhandled target architecture.");
- return -1;
+ llvm_unreachable("Unhandled target architecture.");
}
+
+ llvm_unreachable("Register does not belong to any register set");
}
-Status NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(uint32_t set) {
+Status NativeRegisterContextNetBSD_x86_64::ReadRegisterSet(RegSetKind set) {
switch (set) {
case GPRegSet:
- return DoRegisterSet(PT_GETREGS, &m_gpr);
- case FPRegSet:
-#if defined(__x86_64__)
- return DoRegisterSet(PT_GETFPREGS, &m_fpr);
-#else
- return DoRegisterSet(PT_GETXMMREGS, &m_fpr);
-#endif
+ return DoRegisterSet(PT_GETREGS, m_gpr.data());
case DBRegSet:
- return DoRegisterSet(PT_GETDBREGS, &m_dbr);
- case XStateRegSet:
-#ifdef HAVE_XSTATE
- {
- struct iovec iov = {&m_xstate, sizeof(m_xstate)};
- return DoRegisterSet(PT_GETXSTATE, &iov);
- }
-#else
- return Status("XState is not supported by the kernel");
-#endif
+ return DoRegisterSet(PT_GETDBREGS, m_dbr.data());
+ case FPRegSet:
+ case YMMRegSet:
+ case MPXRegSet: {
+ struct iovec iov = {m_xstate.data(), m_xstate.size()};
+ Status ret = DoRegisterSet(PT_GETXSTATE, &iov);
+ assert(reinterpret_cast<xstate *>(m_xstate.data())->xs_rfbm & XCR0_X87);
+ return ret;
+ }
}
llvm_unreachable("NativeRegisterContextNetBSD_x86_64::ReadRegisterSet");
}
-Status NativeRegisterContextNetBSD_x86_64::WriteRegisterSet(uint32_t set) {
+Status NativeRegisterContextNetBSD_x86_64::WriteRegisterSet(RegSetKind set) {
switch (set) {
case GPRegSet:
- return DoRegisterSet(PT_SETREGS, &m_gpr);
- case FPRegSet:
-#if defined(__x86_64__)
- return DoRegisterSet(PT_SETFPREGS, &m_fpr);
-#else
- return DoRegisterSet(PT_SETXMMREGS, &m_fpr);
-#endif
+ return DoRegisterSet(PT_SETREGS, m_gpr.data());
case DBRegSet:
- return DoRegisterSet(PT_SETDBREGS, &m_dbr);
- case XStateRegSet:
-#ifdef HAVE_XSTATE
- {
- struct iovec iov = {&m_xstate, sizeof(m_xstate)};
- return DoRegisterSet(PT_SETXSTATE, &iov);
- }
-#else
- return Status("XState is not supported by the kernel");
-#endif
+ return DoRegisterSet(PT_SETDBREGS, m_dbr.data());
+ case FPRegSet:
+ case YMMRegSet:
+ case MPXRegSet: {
+ struct iovec iov = {&m_xstate, sizeof(m_xstate)};
+ return DoRegisterSet(PT_SETXSTATE, &iov);
+ }
}
llvm_unreachable("NativeRegisterContextNetBSD_x86_64::WriteRegisterSet");
}
@@ -495,8 +399,8 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
return error;
}
- int set = GetSetForNativeRegNum(reg);
- if (set == -1) {
+ llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);
+ if (!opt_set) {
// This is likely an internal register for lldb use only and should not be
// directly queried.
error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
@@ -504,261 +408,40 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info,
return error;
}
- switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
- case llvm::Triple::x86_64:
- break;
- case llvm::Triple::x86:
- reg = RegNumX86ToX86_64(reg);
- break;
- default:
- assert(false && "Unhandled target architecture.");
- error.SetErrorString("Unhandled target architecture.");
- return error;
- }
-
+ RegSetKind set = opt_set.getValue();
error = ReadRegisterSet(set);
if (error.Fail())
return error;
- switch (reg) {
-#if defined(__x86_64__)
- case lldb_rax_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_RAX];
- break;
- case lldb_rbx_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_RBX];
- break;
- case lldb_rcx_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_RCX];
- break;
- case lldb_rdx_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_RDX];
- break;
- case lldb_rdi_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_RDI];
- break;
- case lldb_rsi_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_RSI];
- break;
- case lldb_rbp_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_RBP];
- break;
- case lldb_rsp_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_RSP];
- break;
- case lldb_r8_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_R8];
- break;
- case lldb_r9_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_R9];
- break;
- case lldb_r10_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_R10];
- break;
- case lldb_r11_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_R11];
- break;
- case lldb_r12_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_R12];
- break;
- case lldb_r13_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_R13];
- break;
- case lldb_r14_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_R14];
- break;
- case lldb_r15_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_R15];
- break;
- case lldb_rip_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_RIP];
- break;
- case lldb_rflags_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_RFLAGS];
- break;
- case lldb_cs_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_CS];
- break;
- case lldb_fs_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_FS];
- break;
- case lldb_gs_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_GS];
- break;
- case lldb_ss_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_SS];
- break;
- case lldb_ds_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_DS];
- break;
- case lldb_es_x86_64:
- reg_value = (uint64_t)m_gpr.regs[_REG_ES];
- break;
-#else
- case lldb_rax_x86_64:
- reg_value = (uint32_t)m_gpr.r_eax;
- break;
- case lldb_rbx_x86_64:
- reg_value = (uint32_t)m_gpr.r_ebx;
- break;
- case lldb_rcx_x86_64:
- reg_value = (uint32_t)m_gpr.r_ecx;
- break;
- case lldb_rdx_x86_64:
- reg_value = (uint32_t)m_gpr.r_edx;
- break;
- case lldb_rdi_x86_64:
- reg_value = (uint32_t)m_gpr.r_edi;
- break;
- case lldb_rsi_x86_64:
- reg_value = (uint32_t)m_gpr.r_esi;
- break;
- case lldb_rsp_x86_64:
- reg_value = (uint32_t)m_gpr.r_esp;
- break;
- case lldb_rbp_x86_64:
- reg_value = (uint32_t)m_gpr.r_ebp;
- break;
- case lldb_rip_x86_64:
- reg_value = (uint32_t)m_gpr.r_eip;
- break;
- case lldb_rflags_x86_64:
- reg_value = (uint32_t)m_gpr.r_eflags;
- break;
- case lldb_cs_x86_64:
- reg_value = (uint32_t)m_gpr.r_cs;
- break;
- case lldb_fs_x86_64:
- reg_value = (uint32_t)m_gpr.r_fs;
- break;
- case lldb_gs_x86_64:
- reg_value = (uint32_t)m_gpr.r_gs;
- break;
- case lldb_ss_x86_64:
- reg_value = (uint32_t)m_gpr.r_ss;
- break;
- case lldb_ds_x86_64:
- reg_value = (uint32_t)m_gpr.r_ds;
- break;
- case lldb_es_x86_64:
- reg_value = (uint32_t)m_gpr.r_es;
- break;
-#endif
- case lldb_fctrl_x86_64:
- reg_value = (uint16_t)m_fpr.fxstate.fx_cw;
- break;
- case lldb_fstat_x86_64:
- reg_value = (uint16_t)m_fpr.fxstate.fx_sw;
- break;
- case lldb_ftag_x86_64:
- reg_value = (uint8_t)m_fpr.fxstate.fx_tw;
- break;
- case lldb_fop_x86_64:
- reg_value = (uint64_t)m_fpr.fxstate.fx_opcode;
- break;
- case lldb_fiseg_x86_64:
- reg_value = (uint64_t)m_fpr.fxstate.fx_ip.fa_64;
- break;
- case lldb_fioff_x86_64:
- reg_value = (uint32_t)m_fpr.fxstate.fx_ip.fa_32.fa_off;
- break;
- case lldb_foseg_x86_64:
- reg_value = (uint64_t)m_fpr.fxstate.fx_dp.fa_64;
- break;
- case lldb_fooff_x86_64:
- reg_value = (uint32_t)m_fpr.fxstate.fx_dp.fa_32.fa_off;
- break;
- case lldb_mxcsr_x86_64:
- reg_value = (uint32_t)m_fpr.fxstate.fx_mxcsr;
- break;
- case lldb_mxcsrmask_x86_64:
- reg_value = (uint32_t)m_fpr.fxstate.fx_mxcsr_mask;
- break;
- case lldb_st0_x86_64:
- case lldb_st1_x86_64:
- case lldb_st2_x86_64:
- case lldb_st3_x86_64:
- case lldb_st4_x86_64:
- case lldb_st5_x86_64:
- case lldb_st6_x86_64:
- case lldb_st7_x86_64:
- reg_value.SetBytes(&m_fpr.fxstate.fx_87_ac[reg - lldb_st0_x86_64],
- reg_info->byte_size, endian::InlHostByteOrder());
- break;
- case lldb_mm0_x86_64:
- case lldb_mm1_x86_64:
- case lldb_mm2_x86_64:
- case lldb_mm3_x86_64:
- case lldb_mm4_x86_64:
- case lldb_mm5_x86_64:
- case lldb_mm6_x86_64:
- case lldb_mm7_x86_64:
- reg_value.SetBytes(&m_fpr.fxstate.fx_87_ac[reg - lldb_mm0_x86_64],
- reg_info->byte_size, endian::InlHostByteOrder());
- break;
- case lldb_xmm0_x86_64:
- case lldb_xmm1_x86_64:
- case lldb_xmm2_x86_64:
- case lldb_xmm3_x86_64:
- case lldb_xmm4_x86_64:
- case lldb_xmm5_x86_64:
- case lldb_xmm6_x86_64:
- case lldb_xmm7_x86_64:
- case lldb_xmm8_x86_64:
- case lldb_xmm9_x86_64:
- case lldb_xmm10_x86_64:
- case lldb_xmm11_x86_64:
- case lldb_xmm12_x86_64:
- case lldb_xmm13_x86_64:
- case lldb_xmm14_x86_64:
- case lldb_xmm15_x86_64:
- reg_value.SetBytes(&m_fpr.fxstate.fx_xmm[reg - lldb_xmm0_x86_64],
- reg_info->byte_size, endian::InlHostByteOrder());
+ switch (set) {
+ case GPRegSet:
+ case FPRegSet:
+ case DBRegSet: {
+ void *data = GetOffsetRegSetData(set, reg_info->byte_offset);
+ FXSAVE *fpr = reinterpret_cast<FXSAVE *>(m_xstate.data() +
+ offsetof(xstate, xs_fxsave));
+ if (data == &fpr->ftag) // ftag
+ reg_value.SetUInt16(
+ AbridgedToFullTagWord(fpr->ftag, fpr->fstat, fpr->stmm));
+ else
+ reg_value.SetBytes(data, reg_info->byte_size, endian::InlHostByteOrder());
break;
- case lldb_ymm0_x86_64:
- case lldb_ymm1_x86_64:
- case lldb_ymm2_x86_64:
- case lldb_ymm3_x86_64:
- case lldb_ymm4_x86_64:
- case lldb_ymm5_x86_64:
- case lldb_ymm6_x86_64:
- case lldb_ymm7_x86_64:
- case lldb_ymm8_x86_64:
- case lldb_ymm9_x86_64:
- case lldb_ymm10_x86_64:
- case lldb_ymm11_x86_64:
- case lldb_ymm12_x86_64:
- case lldb_ymm13_x86_64:
- case lldb_ymm14_x86_64:
- case lldb_ymm15_x86_64:
-#ifdef HAVE_XSTATE
- if (!(m_xstate.xs_rfbm & XCR0_SSE) ||
- !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) {
- error.SetErrorStringWithFormat("register \"%s\" not supported by CPU/kernel",
- reg_info->name);
+ }
+ case YMMRegSet: {
+ llvm::Optional<YMMSplitPtr> ymm_reg = GetYMMSplitReg(reg);
+ if (!ymm_reg) {
+ error.SetErrorStringWithFormat(
+ "register \"%s\" not supported by CPU/kernel", reg_info->name);
} else {
- uint32_t reg_index = reg - lldb_ymm0_x86_64;
- YMMReg ymm = XStateToYMM(
- m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
- m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes);
+ YMMReg ymm = XStateToYMM(ymm_reg->xmm, ymm_reg->ymm_hi);
reg_value.SetBytes(ymm.bytes, reg_info->byte_size,
endian::InlHostByteOrder());
}
-#else
- error.SetErrorString("XState queries not supported by the kernel");
-#endif
- break;
- case lldb_dr0_x86_64:
- case lldb_dr1_x86_64:
- case lldb_dr2_x86_64:
- case lldb_dr3_x86_64:
- case lldb_dr4_x86_64:
- case lldb_dr5_x86_64:
- case lldb_dr6_x86_64:
- case lldb_dr7_x86_64:
- reg_value = (uint64_t)m_dbr.dr[reg - lldb_dr0_x86_64];
break;
}
+ case MPXRegSet:
+ llvm_unreachable("MPX regset should have returned error");
+ }
return error;
}
@@ -783,8 +466,8 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
return error;
}
- int set = GetSetForNativeRegNum(reg);
- if (set == -1) {
+ llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);
+ if (!opt_set) {
// This is likely an internal register for lldb use only and should not be
// directly queried.
error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
@@ -792,262 +475,54 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister(
return error;
}
- switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
- case llvm::Triple::x86_64:
- break;
- case llvm::Triple::x86:
- reg = RegNumX86ToX86_64(reg);
- break;
- default:
- assert(false && "Unhandled target architecture.");
- error.SetErrorString("Unhandled target architecture.");
- return error;
- }
+ RegSetKind set = opt_set.getValue();
+ uint64_t new_xstate_bv = 0;
error = ReadRegisterSet(set);
if (error.Fail())
return error;
- switch (reg) {
-#if defined(__x86_64__)
- case lldb_rax_x86_64:
- m_gpr.regs[_REG_RAX] = reg_value.GetAsUInt64();
- break;
- case lldb_rbx_x86_64:
- m_gpr.regs[_REG_RBX] = reg_value.GetAsUInt64();
- break;
- case lldb_rcx_x86_64:
- m_gpr.regs[_REG_RCX] = reg_value.GetAsUInt64();
- break;
- case lldb_rdx_x86_64:
- m_gpr.regs[_REG_RDX] = reg_value.GetAsUInt64();
- break;
- case lldb_rdi_x86_64:
- m_gpr.regs[_REG_RDI] = reg_value.GetAsUInt64();
- break;
- case lldb_rsi_x86_64:
- m_gpr.regs[_REG_RSI] = reg_value.GetAsUInt64();
- break;
- case lldb_rbp_x86_64:
- m_gpr.regs[_REG_RBP] = reg_value.GetAsUInt64();
- break;
- case lldb_rsp_x86_64:
- m_gpr.regs[_REG_RSP] = reg_value.GetAsUInt64();
- break;
- case lldb_r8_x86_64:
- m_gpr.regs[_REG_R8] = reg_value.GetAsUInt64();
- break;
- case lldb_r9_x86_64:
- m_gpr.regs[_REG_R9] = reg_value.GetAsUInt64();
- break;
- case lldb_r10_x86_64:
- m_gpr.regs[_REG_R10] = reg_value.GetAsUInt64();
- break;
- case lldb_r11_x86_64:
- m_gpr.regs[_REG_R11] = reg_value.GetAsUInt64();
- break;
- case lldb_r12_x86_64:
- m_gpr.regs[_REG_R12] = reg_value.GetAsUInt64();
- break;
- case lldb_r13_x86_64:
- m_gpr.regs[_REG_R13] = reg_value.GetAsUInt64();
- break;
- case lldb_r14_x86_64:
- m_gpr.regs[_REG_R14] = reg_value.GetAsUInt64();
- break;
- case lldb_r15_x86_64:
- m_gpr.regs[_REG_R15] = reg_value.GetAsUInt64();
- break;
- case lldb_rip_x86_64:
- m_gpr.regs[_REG_RIP] = reg_value.GetAsUInt64();
- break;
- case lldb_rflags_x86_64:
- m_gpr.regs[_REG_RFLAGS] = reg_value.GetAsUInt64();
- break;
- case lldb_cs_x86_64:
- m_gpr.regs[_REG_CS] = reg_value.GetAsUInt64();
- break;
- case lldb_fs_x86_64:
- m_gpr.regs[_REG_FS] = reg_value.GetAsUInt64();
- break;
- case lldb_gs_x86_64:
- m_gpr.regs[_REG_GS] = reg_value.GetAsUInt64();
- break;
- case lldb_ss_x86_64:
- m_gpr.regs[_REG_SS] = reg_value.GetAsUInt64();
- break;
- case lldb_ds_x86_64:
- m_gpr.regs[_REG_DS] = reg_value.GetAsUInt64();
- break;
- case lldb_es_x86_64:
- m_gpr.regs[_REG_ES] = reg_value.GetAsUInt64();
- break;
-#else
- case lldb_rax_x86_64:
- m_gpr.r_eax = reg_value.GetAsUInt32();
- break;
- case lldb_rbx_x86_64:
- m_gpr.r_ebx = reg_value.GetAsUInt32();
- break;
- case lldb_rcx_x86_64:
- m_gpr.r_ecx = reg_value.GetAsUInt32();
- break;
- case lldb_rdx_x86_64:
- m_gpr.r_edx = reg_value.GetAsUInt32();
- break;
- case lldb_rdi_x86_64:
- m_gpr.r_edi = reg_value.GetAsUInt32();
- break;
- case lldb_rsi_x86_64:
- m_gpr.r_esi = reg_value.GetAsUInt32();
- break;
- case lldb_rsp_x86_64:
- m_gpr.r_esp = reg_value.GetAsUInt32();
- break;
- case lldb_rbp_x86_64:
- m_gpr.r_ebp = reg_value.GetAsUInt32();
- break;
- case lldb_rip_x86_64:
- m_gpr.r_eip = reg_value.GetAsUInt32();
- break;
- case lldb_rflags_x86_64:
- m_gpr.r_eflags = reg_value.GetAsUInt32();
- break;
- case lldb_cs_x86_64:
- m_gpr.r_cs = reg_value.GetAsUInt32();
- break;
- case lldb_fs_x86_64:
- m_gpr.r_fs = reg_value.GetAsUInt32();
- break;
- case lldb_gs_x86_64:
- m_gpr.r_gs = reg_value.GetAsUInt32();
- break;
- case lldb_ss_x86_64:
- m_gpr.r_ss = reg_value.GetAsUInt32();
- break;
- case lldb_ds_x86_64:
- m_gpr.r_ds = reg_value.GetAsUInt32();
- break;
- case lldb_es_x86_64:
- m_gpr.r_es = reg_value.GetAsUInt32();
- break;
-#endif
- case lldb_fctrl_x86_64:
- m_fpr.fxstate.fx_cw = reg_value.GetAsUInt16();
- break;
- case lldb_fstat_x86_64:
- m_fpr.fxstate.fx_sw = reg_value.GetAsUInt16();
- break;
- case lldb_ftag_x86_64:
- m_fpr.fxstate.fx_tw = reg_value.GetAsUInt8();
- break;
- case lldb_fop_x86_64:
- m_fpr.fxstate.fx_opcode = reg_value.GetAsUInt16();
- break;
- case lldb_fiseg_x86_64:
- m_fpr.fxstate.fx_ip.fa_64 = reg_value.GetAsUInt64();
- break;
- case lldb_fioff_x86_64:
- m_fpr.fxstate.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32();
- break;
- case lldb_foseg_x86_64:
- m_fpr.fxstate.fx_dp.fa_64 = reg_value.GetAsUInt64();
- break;
- case lldb_fooff_x86_64:
- m_fpr.fxstate.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32();
- break;
- case lldb_mxcsr_x86_64:
- m_fpr.fxstate.fx_mxcsr = reg_value.GetAsUInt32();
- break;
- case lldb_mxcsrmask_x86_64:
- m_fpr.fxstate.fx_mxcsr_mask = reg_value.GetAsUInt32();
- break;
- case lldb_st0_x86_64:
- case lldb_st1_x86_64:
- case lldb_st2_x86_64:
- case lldb_st3_x86_64:
- case lldb_st4_x86_64:
- case lldb_st5_x86_64:
- case lldb_st6_x86_64:
- case lldb_st7_x86_64:
- ::memcpy(&m_fpr.fxstate.fx_87_ac[reg - lldb_st0_x86_64],
- reg_value.GetBytes(), reg_value.GetByteSize());
- break;
- case lldb_mm0_x86_64:
- case lldb_mm1_x86_64:
- case lldb_mm2_x86_64:
- case lldb_mm3_x86_64:
- case lldb_mm4_x86_64:
- case lldb_mm5_x86_64:
- case lldb_mm6_x86_64:
- case lldb_mm7_x86_64:
- ::memcpy(&m_fpr.fxstate.fx_87_ac[reg - lldb_mm0_x86_64],
+ switch (set) {
+ case GPRegSet:
+ case DBRegSet:
+ ::memcpy(GetOffsetRegSetData(set, reg_info->byte_offset),
reg_value.GetBytes(), reg_value.GetByteSize());
break;
- case lldb_xmm0_x86_64:
- case lldb_xmm1_x86_64:
- case lldb_xmm2_x86_64:
- case lldb_xmm3_x86_64:
- case lldb_xmm4_x86_64:
- case lldb_xmm5_x86_64:
- case lldb_xmm6_x86_64:
- case lldb_xmm7_x86_64:
- case lldb_xmm8_x86_64:
- case lldb_xmm9_x86_64:
- case lldb_xmm10_x86_64:
- case lldb_xmm11_x86_64:
- case lldb_xmm12_x86_64:
- case lldb_xmm13_x86_64:
- case lldb_xmm14_x86_64:
- case lldb_xmm15_x86_64:
- ::memcpy(&m_fpr.fxstate.fx_xmm[reg - lldb_xmm0_x86_64],
- reg_value.GetBytes(), reg_value.GetByteSize());
+ case FPRegSet: {
+ void *data = GetOffsetRegSetData(set, reg_info->byte_offset);
+ FXSAVE *fpr = reinterpret_cast<FXSAVE *>(m_xstate.data() +
+ offsetof(xstate, xs_fxsave));
+ if (data == &fpr->ftag) // ftag
+ fpr->ftag = FullToAbridgedTagWord(reg_value.GetAsUInt16());
+ else
+ ::memcpy(data, reg_value.GetBytes(), reg_value.GetByteSize());
+ if (data >= &fpr->xmm)
+ new_xstate_bv |= XCR0_SSE;
+ else if (data >= &fpr->mxcsr && data < &fpr->stmm)
+ new_xstate_bv |= XCR0_SSE;
+ else
+ new_xstate_bv |= XCR0_X87;
break;
- case lldb_ymm0_x86_64:
- case lldb_ymm1_x86_64:
- case lldb_ymm2_x86_64:
- case lldb_ymm3_x86_64:
- case lldb_ymm4_x86_64:
- case lldb_ymm5_x86_64:
- case lldb_ymm6_x86_64:
- case lldb_ymm7_x86_64:
- case lldb_ymm8_x86_64:
- case lldb_ymm9_x86_64:
- case lldb_ymm10_x86_64:
- case lldb_ymm11_x86_64:
- case lldb_ymm12_x86_64:
- case lldb_ymm13_x86_64:
- case lldb_ymm14_x86_64:
- case lldb_ymm15_x86_64:
-#ifdef HAVE_XSTATE
- if (!(m_xstate.xs_rfbm & XCR0_SSE) ||
- !(m_xstate.xs_rfbm & XCR0_YMM_Hi128)) {
- error.SetErrorStringWithFormat("register \"%s\" not supported by CPU/kernel",
- reg_info->name);
+ }
+ case YMMRegSet: {
+ llvm::Optional<YMMSplitPtr> ymm_reg = GetYMMSplitReg(reg);
+ if (!ymm_reg) {
+ error.SetErrorStringWithFormat(
+ "register \"%s\" not supported by CPU/kernel", reg_info->name);
} else {
- uint32_t reg_index = reg - lldb_ymm0_x86_64;
YMMReg ymm;
::memcpy(ymm.bytes, reg_value.GetBytes(), reg_value.GetByteSize());
- YMMToXState(ymm,
- m_xstate.xs_fxsave.fx_xmm[reg_index].xmm_bytes,
- m_xstate.xs_ymm_hi128.xs_ymm[reg_index].ymm_bytes);
+ YMMToXState(ymm, ymm_reg->xmm, ymm_reg->ymm_hi);
+ new_xstate_bv |= XCR0_SSE | XCR0_YMM_Hi128;
}
-#else
- error.SetErrorString("XState not supported by the kernel");
-#endif
- break;
- case lldb_dr0_x86_64:
- case lldb_dr1_x86_64:
- case lldb_dr2_x86_64:
- case lldb_dr3_x86_64:
- case lldb_dr4_x86_64:
- case lldb_dr5_x86_64:
- case lldb_dr6_x86_64:
- case lldb_dr7_x86_64:
- m_dbr.dr[reg - lldb_dr0_x86_64] = reg_value.GetAsUInt64();
break;
}
+ case MPXRegSet:
+ llvm_unreachable("MPX regset should have returned error");
+ }
+ if (new_xstate_bv != 0)
+ reinterpret_cast<xstate *>(m_xstate.data())->xs_xstate_bv |= new_xstate_bv;
return WriteRegisterSet(set);
}
@@ -1061,7 +536,7 @@ Status NativeRegisterContextNetBSD_x86_64::ReadAllRegisterValues(
return error;
uint8_t *dst = data_sp->GetBytes();
- ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize());
+ ::memcpy(dst, m_gpr.data(), GetRegisterInfoInterface().GetGPRSize());
dst += GetRegisterInfoInterface().GetGPRSize();
return error;
@@ -1094,7 +569,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues(
__FUNCTION__);
return error;
}
- ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize());
+ ::memcpy(m_gpr.data(), src, GetRegisterInfoInterface().GetGPRSize());
error = WriteRegisterSet(GPRegSet);
if (error.Fail())
@@ -1104,260 +579,66 @@ Status NativeRegisterContextNetBSD_x86_64::WriteAllRegisterValues(
return error;
}
-int NativeRegisterContextNetBSD_x86_64::GetDR(int num) const {
- assert(num >= 0 && num <= 7);
- switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
- case llvm::Triple::x86:
- return lldb_dr0_i386 + num;
- case llvm::Triple::x86_64:
- return lldb_dr0_x86_64 + num;
- default:
- return -1;
- }
-}
-
-Status NativeRegisterContextNetBSD_x86_64::IsWatchpointHit(uint32_t wp_index,
- bool &is_hit) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Status("Watchpoint index out of range");
-
- RegisterValue reg_value;
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(GetDR(6));
- Status error = ReadRegister(reg_info, reg_value);
- if (error.Fail()) {
- is_hit = false;
- return error;
- }
-
- uint64_t status_bits = reg_value.GetAsUInt64();
-
- is_hit = status_bits & (1 << wp_index);
-
- return error;
-}
-
-Status NativeRegisterContextNetBSD_x86_64::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;
- Status 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 Status();
-}
-
-Status NativeRegisterContextNetBSD_x86_64::IsWatchpointVacant(uint32_t wp_index,
- bool &is_vacant) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Status("Watchpoint index out of range");
+llvm::Error NativeRegisterContextNetBSD_x86_64::CopyHardwareWatchpointsFrom(
+ NativeRegisterContextNetBSD &source) {
+ auto &r_source = static_cast<NativeRegisterContextNetBSD_x86_64 &>(source);
+ // NB: This implicitly reads the whole dbreg set.
+ RegisterValue dr7;
+ Status res = r_source.ReadRegister(GetDR(7), dr7);
+ if (!res.Fail()) {
+ // copy dbregs only if any watchpoints were set
+ if ((dr7.GetAsUInt64() & 0xFF) == 0)
+ return llvm::Error::success();
- RegisterValue reg_value;
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(GetDR(7));
- Status error = ReadRegister(reg_info, reg_value);
- if (error.Fail()) {
- is_vacant = false;
- return error;
+ m_dbr = r_source.m_dbr;
+ res = WriteRegisterSet(DBRegSet);
}
-
- uint64_t control_bits = reg_value.GetAsUInt64();
-
- is_vacant = !(control_bits & (1 << (2 * wp_index + 1)));
-
- return error;
+ return res.ToError();
}
-Status NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpointWithIndex(
- lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
-
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Status("Watchpoint index out of range");
-
- // Read only watchpoints aren't supported on x86_64. Fall back to read/write
- // waitchpoints instead.
- // TODO: Add logic to detect when a write happens and ignore that watchpoint
- // hit.
- if (watch_flags == 0x2)
- watch_flags = 0x3;
-
- if (watch_flags != 0x1 && watch_flags != 0x3)
- return Status("Invalid read/write bits for watchpoint");
-
- if (size != 1 && size != 2 && size != 4 && size != 8)
- return Status("Invalid size for watchpoint");
-
- bool is_vacant;
- Status error = IsWatchpointVacant(wp_index, is_vacant);
- if (error.Fail())
- return error;
- if (!is_vacant)
- return Status("Watchpoint index not vacant");
-
- const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7));
- RegisterValue dr7_value;
- error = ReadRegister(reg_info_dr7, dr7_value);
- if (error.Fail())
- return error;
-
- // for watchpoints 0, 1, 2, or 3, respectively, set bits 1, 3, 5, or 7
- uint64_t enable_bit = 1 << (2 * wp_index + 1);
-
- // set bits 16-17, 20-21, 24-25, or 28-29
- // with 0b01 for write, and 0b11 for read/write
- uint64_t rw_bits = watch_flags << (16 + 4 * wp_index);
-
- // set bits 18-19, 22-23, 26-27, or 30-31
- // with 0b00, 0b01, 0b10, or 0b11
- // for 1, 2, 8 (if supported), or 4 bytes, respectively
- uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index);
-
- uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
-
- uint64_t control_bits = dr7_value.GetAsUInt64() & ~bit_mask;
-
- control_bits |= enable_bit | rw_bits | size_bits;
-
- const RegisterInfo *const reg_info_drN =
- GetRegisterInfoAtIndex(GetDR(wp_index));
- RegisterValue drN_value;
- error = ReadRegister(reg_info_drN, drN_value);
- if (error.Fail())
- return error;
-
- // clear dr6 if address or bits changed (i.e. we're not reenabling the same
- // watchpoint)
- if (drN_value.GetAsUInt64() != addr ||
- (dr7_value.GetAsUInt64() & bit_mask) != (rw_bits | size_bits)) {
- ClearWatchpointHit(wp_index);
-
- error = WriteRegister(reg_info_drN, RegisterValue(addr));
- if (error.Fail())
- return error;
+uint8_t *
+NativeRegisterContextNetBSD_x86_64::GetOffsetRegSetData(RegSetKind set,
+ size_t reg_offset) {
+ uint8_t *base;
+ switch (set) {
+ case GPRegSet:
+ base = m_gpr.data();
+ break;
+ case FPRegSet:
+ base = m_xstate.data() + offsetof(xstate, xs_fxsave);
+ break;
+ case DBRegSet:
+ base = m_dbr.data();
+ break;
+ case YMMRegSet:
+ llvm_unreachable("GetRegSetData() is unsuitable for this regset.");
+ case MPXRegSet:
+ llvm_unreachable("MPX regset should have returned error");
}
-
- error = WriteRegister(reg_info_dr7, RegisterValue(control_bits));
- if (error.Fail())
- return error;
-
- error.Clear();
- return error;
-}
-
-bool NativeRegisterContextNetBSD_x86_64::ClearHardwareWatchpoint(
- uint32_t wp_index) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return false;
-
- // for watchpoints 0, 1, 2, or 3, respectively, clear bits 0-1, 2-3, 4-5
- // or 6-7 of the debug control register (DR7)
- const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7));
- RegisterValue reg_value;
- Status error = ReadRegister(reg_info_dr7, reg_value);
- if (error.Fail())
- return false;
- uint64_t bit_mask = 0x3 << (2 * wp_index);
- uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
-
- return WriteRegister(reg_info_dr7, RegisterValue(control_bits)).Success();
+ assert(reg_offset >= m_regset_offsets[set]);
+ return base + (reg_offset - m_regset_offsets[set]);
}
-Status NativeRegisterContextNetBSD_x86_64::ClearWatchpointHit(uint32_t wp_index) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Status("Watchpoint index out of range");
+llvm::Optional<NativeRegisterContextNetBSD_x86_64::YMMSplitPtr>
+NativeRegisterContextNetBSD_x86_64::GetYMMSplitReg(uint32_t reg) {
+ auto xst = reinterpret_cast<xstate *>(m_xstate.data());
+ if (!(xst->xs_rfbm & XCR0_SSE) || !(xst->xs_rfbm & XCR0_YMM_Hi128))
+ return llvm::None;
- // for watchpoints 0, 1, 2, or 3, respectively, check bits 0, 1, 2, or 3 of
- // the debug status register (DR6)
- const RegisterInfo *const reg_info_dr6 = GetRegisterInfoAtIndex(GetDR(6));
- RegisterValue reg_value;
- Status error = ReadRegister(reg_info_dr6, reg_value);
- if (error.Fail())
- return error;
-
- uint64_t bit_mask = 1 << wp_index;
- uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
- return WriteRegister(reg_info_dr6, RegisterValue(status_bits));
-}
-
-Status NativeRegisterContextNetBSD_x86_64::ClearAllHardwareWatchpoints() {
- RegisterValue reg_value;
-
- // clear bits {0-4} of the debug status register (DR6)
- const RegisterInfo *const reg_info_dr6 = GetRegisterInfoAtIndex(GetDR(6));
- Status error = ReadRegister(reg_info_dr6, reg_value);
- if (error.Fail())
- return error;
- uint64_t bit_mask = 0xF;
- uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
- error = WriteRegister(reg_info_dr6, RegisterValue(status_bits));
- if (error.Fail())
- return error;
-
- // clear bits {0-7,16-31} of the debug control register (DR7)
- const RegisterInfo *const reg_info_dr7 = GetRegisterInfoAtIndex(GetDR(7));
- error = ReadRegister(reg_info_dr7, reg_value);
- if (error.Fail())
- return error;
- bit_mask = 0xFF | (0xFFFF << 16);
- uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
- return WriteRegister(reg_info_dr7, RegisterValue(control_bits));
-}
-
-uint32_t NativeRegisterContextNetBSD_x86_64::SetHardwareWatchpoint(
- lldb::addr_t addr, size_t size, uint32_t watch_flags) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) {
- bool is_vacant;
- Status error = IsWatchpointVacant(wp_index, is_vacant);
- if (is_vacant) {
- error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
- if (error.Success())
- return wp_index;
- }
- if (error.Fail() && log) {
- LLDB_LOGF(log, "NativeRegisterContextNetBSD_x86_64::%s Error: %s",
- __FUNCTION__, error.AsCString());
- }
+ uint32_t reg_index;
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::x86:
+ reg_index = reg - lldb_ymm0_i386;
+ break;
+ case llvm::Triple::x86_64:
+ reg_index = reg - lldb_ymm0_x86_64;
+ break;
+ default:
+ llvm_unreachable("Unhandled target architecture.");
}
- return LLDB_INVALID_INDEX32;
-}
-
-lldb::addr_t
-NativeRegisterContextNetBSD_x86_64::GetWatchpointAddress(uint32_t wp_index) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return LLDB_INVALID_ADDRESS;
- RegisterValue reg_value;
- const RegisterInfo *const reg_info_drN =
- GetRegisterInfoAtIndex(GetDR(wp_index));
- if (ReadRegister(reg_info_drN, reg_value).Fail())
- return LLDB_INVALID_ADDRESS;
- return reg_value.GetAsUInt64();
-}
-uint32_t NativeRegisterContextNetBSD_x86_64::NumSupportedHardwareWatchpoints() {
- // Available debug address registers: dr0, dr1, dr2, dr3
- return 4;
-}
-
-Status NativeRegisterContextNetBSD_x86_64::CopyHardwareWatchpointsFrom(
- NativeRegisterContextNetBSD &source) {
- auto &r_source = static_cast<NativeRegisterContextNetBSD_x86_64&>(source);
- Status res = r_source.ReadRegisterSet(DBRegSet);
- if (!res.Fail()) {
- // copy dbregs only if any watchpoints were set
- if ((r_source.m_dbr.dr[7] & 0xFF) == 0)
- return res;
-
- m_dbr = r_source.m_dbr;
- res = WriteRegisterSet(DBRegSet);
- }
- return res;
+ return YMMSplitPtr{&xst->xs_fxsave.fx_xmm[reg_index],
+ &xst->xs_ymm_hi128.xs_ymm[reg_index]};
}
#endif // defined(__x86_64__)
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
index 6c0632f3bce8..31005952dd75 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
@@ -18,20 +18,21 @@
#include <machine/reg.h>
// clang-format on
+#include <array>
+
#include "Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h"
#include "Plugins/Process/Utility/RegisterContext_x86.h"
+#include "Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h"
#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
-#if defined(PT_GETXSTATE) && defined(PT_SETXSTATE)
-#define HAVE_XSTATE
-#endif
-
namespace lldb_private {
namespace process_netbsd {
class NativeProcessNetBSD;
-class NativeRegisterContextNetBSD_x86_64 : public NativeRegisterContextNetBSD {
+class NativeRegisterContextNetBSD_x86_64
+ : public NativeRegisterContextNetBSD,
+ public NativeRegisterContextDBReg_x86 {
public:
NativeRegisterContextNetBSD_x86_64(const ArchSpec &target_arch,
NativeThreadProtocol &native_thread);
@@ -49,54 +50,39 @@ public:
Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
-
- Status GetWatchpointHitIndex(uint32_t &wp_index,
- lldb::addr_t trap_addr) override;
-
- Status IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
-
- bool ClearHardwareWatchpoint(uint32_t wp_index) override;
-
- Status ClearWatchpointHit(uint32_t wp_index) override;
-
- Status ClearAllHardwareWatchpoints() override;
-
- Status SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
- uint32_t watch_flags,
- uint32_t wp_index);
-
- 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;
-
- Status
+ llvm::Error
CopyHardwareWatchpointsFrom(NativeRegisterContextNetBSD &source) override;
private:
// Private member types.
- enum { GPRegSet, FPRegSet, XStateRegSet, DBRegSet };
+ enum RegSetKind {
+ GPRegSet,
+ FPRegSet,
+ DBRegSet,
+ MaxRegularRegSet = DBRegSet,
+ YMMRegSet,
+ MPXRegSet,
+ MaxRegSet = MPXRegSet,
+ };
// Private member variables.
- struct reg m_gpr;
-#if defined(__x86_64__)
- struct fpreg m_fpr;
-#else
- struct xmmregs m_fpr;
-#endif
- struct dbreg m_dbr;
-#ifdef HAVE_XSTATE
- struct xstate m_xstate;
-#endif
-
- int GetSetForNativeRegNum(int reg_num) const;
- int GetDR(int num) const;
-
- Status ReadRegisterSet(uint32_t set);
- Status WriteRegisterSet(uint32_t set);
+ std::array<uint8_t, sizeof(struct reg)> m_gpr;
+ std::array<uint8_t, sizeof(struct xstate)> m_xstate;
+ std::array<uint8_t, sizeof(struct dbreg)> m_dbr;
+ std::array<size_t, MaxRegularRegSet + 1> m_regset_offsets;
+
+ llvm::Optional<RegSetKind> GetSetForNativeRegNum(uint32_t reg_num) const;
+
+ Status ReadRegisterSet(RegSetKind set);
+ Status WriteRegisterSet(RegSetKind set);
+
+ uint8_t *GetOffsetRegSetData(RegSetKind set, size_t reg_offset);
+
+ struct YMMSplitPtr {
+ void *xmm;
+ void *ymm_hi;
+ };
+ llvm::Optional<YMMSplitPtr> GetYMMSplitReg(uint32_t reg);
};
} // namespace process_netbsd
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
index fe76fb40e0b3..1a3fd4d646ae 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
@@ -116,8 +116,6 @@ void NativeThreadNetBSD::SetStoppedByExec() {
}
void NativeThreadNetBSD::SetStoppedByWatchpoint(uint32_t wp_index) {
- SetStopped();
-
lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
std::ostringstream ostr;
@@ -126,8 +124,8 @@ void NativeThreadNetBSD::SetStoppedByWatchpoint(uint32_t wp_index) {
ostr << " " << GetRegisterContext().GetWatchpointHitAddress(wp_index);
+ SetStopped();
m_stop_description = ostr.str();
-
m_stop_info.reason = StopReason::eStopReasonWatchpoint;
m_stop_info.details.signal.signo = SIGTRAP;
}
@@ -204,7 +202,6 @@ lldb::StateType NativeThreadNetBSD::GetState() { return m_state; }
bool NativeThreadNetBSD::GetStopReason(ThreadStopInfo &stop_info,
std::string &description) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
-
description.clear();
switch (m_state) {
@@ -239,14 +236,14 @@ NativeRegisterContextNetBSD &NativeThreadNetBSD::GetRegisterContext() {
Status NativeThreadNetBSD::SetWatchpoint(lldb::addr_t addr, size_t size,
uint32_t watch_flags, bool hardware) {
+ assert(m_state == eStateStopped);
if (!hardware)
return Status("not implemented");
- if (m_state == eStateLaunching)
- return Status();
Status error = RemoveWatchpoint(addr);
if (error.Fail())
return error;
- uint32_t wp_index = GetRegisterContext().SetHardwareWatchpoint(addr, size, watch_flags);
+ uint32_t wp_index =
+ GetRegisterContext().SetHardwareWatchpoint(addr, size, watch_flags);
if (wp_index == LLDB_INVALID_INDEX32)
return Status("Setting hardware watchpoint failed.");
m_watchpoint_index_map.insert({addr, wp_index});
@@ -266,9 +263,7 @@ Status NativeThreadNetBSD::RemoveWatchpoint(lldb::addr_t addr) {
Status NativeThreadNetBSD::SetHardwareBreakpoint(lldb::addr_t addr,
size_t size) {
- if (m_state == eStateLaunching)
- return Status();
-
+ assert(m_state == eStateStopped);
Status error = RemoveHardwareBreakpoint(addr);
if (error.Fail())
return error;
@@ -296,10 +291,11 @@ Status NativeThreadNetBSD::RemoveHardwareBreakpoint(lldb::addr_t addr) {
return Status("Clearing hardware breakpoint failed.");
}
-Status NativeThreadNetBSD::CopyWatchpointsFrom(NativeThreadNetBSD &source) {
- Status s = GetRegisterContext().CopyHardwareWatchpointsFrom(
+llvm::Error
+NativeThreadNetBSD::CopyWatchpointsFrom(NativeThreadNetBSD &source) {
+ llvm::Error s = GetRegisterContext().CopyHardwareWatchpointsFrom(
source.GetRegisterContext());
- if (!s.Fail()) {
+ if (!s) {
m_watchpoint_index_map = source.m_watchpoint_index_map;
m_hw_break_index_map = source.m_hw_break_index_map;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
index 89b61ef86722..d4e21bd2bdaa 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
@@ -64,7 +64,7 @@ private:
void SetRunning();
void SetStepping();
- Status CopyWatchpointsFrom(NativeThreadNetBSD& source);
+ llvm::Error CopyWatchpointsFrom(NativeThreadNetBSD& source);
// Member Variables
lldb::StateType m_state;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.cpp
index 579077b45bf9..c6ede61cfe1b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.cpp
@@ -58,6 +58,18 @@ CrashReason GetCrashReasonForSIGSEGV(const siginfo_t &info) {
#endif
case SEGV_BNDERR:
return CrashReason::eBoundViolation;
+#ifdef __linux__
+#ifndef SEGV_MTEAERR
+#define SEGV_MTEAERR 8
+#endif
+ case SEGV_MTEAERR:
+ return CrashReason::eAsyncTagCheckFault;
+#ifndef SEGV_MTESERR
+#define SEGV_MTESERR 9
+#endif
+ case SEGV_MTESERR:
+ return CrashReason::eSyncTagCheckFault;
+#endif // __linux__
}
return CrashReason::eInvalidCrashReason;
@@ -166,6 +178,13 @@ std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr) {
case CrashReason::eBoundViolation:
str = "signal SIGSEGV: bound violation";
break;
+ case CrashReason::eAsyncTagCheckFault:
+ str = "signal SIGSEGV: async tag check fault";
+ break;
+ case CrashReason::eSyncTagCheckFault:
+ str = "signal SIGSEGV: sync tag check fault";
+ AppendFaultAddr(str, fault_addr);
+ break;
case CrashReason::eIllegalOpcode:
str = "signal SIGILL: illegal instruction";
break;
@@ -246,6 +265,12 @@ const char *CrashReasonAsString(CrashReason reason) {
case CrashReason::eBoundViolation:
str = "eBoundViolation";
break;
+ case CrashReason::eAsyncTagCheckFault:
+ str = "eAsyncTagCheckFault";
+ break;
+ case CrashReason::eSyncTagCheckFault:
+ str = "eSyncTagCheckFault";
+ break;
// SIGILL crash reasons.
case CrashReason::eIllegalOpcode:
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h
index 9b4784a1e68e..f5213891d976 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h
@@ -22,6 +22,8 @@ enum class CrashReason {
eInvalidAddress,
ePrivilegedAddress,
eBoundViolation,
+ eAsyncTagCheckFault,
+ eSyncTagCheckFault,
// SIGILL crash reasons.
eIllegalOpcode,
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.cpp
index 685d9d0824f6..c4f45f759a33 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.cpp
@@ -82,6 +82,7 @@ const char *AuxVector::GetEntryName(EntryType type) const {
case ENTRY_NAME(AUXV_AT_SECURE); break;
case ENTRY_NAME(AUXV_AT_BASE_PLATFORM); break;
case ENTRY_NAME(AUXV_AT_RANDOM); break;
+ case ENTRY_NAME(AUXV_AT_HWCAP2); break;
case ENTRY_NAME(AUXV_AT_EXECFN); break;
case ENTRY_NAME(AUXV_AT_SYSINFO); break;
case ENTRY_NAME(AUXV_AT_SYSINFO_EHDR); break;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.h
index c8c8b1249413..07a0010e198f 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/AuxVector.h
@@ -50,6 +50,7 @@ public:
AUXV_AT_SECURE = 23, ///< Boolean, was exec setuid-like?
AUXV_AT_BASE_PLATFORM = 24, ///< String identifying real platforms.
AUXV_AT_RANDOM = 25, ///< Address of 16 random bytes.
+ AUXV_AT_HWCAP2 = 26, ///< Extension of AT_HWCAP.
AUXV_AT_EXECFN = 31, ///< Filename of executable.
AUXV_AT_SYSINFO = 32, ///< Pointer to the global system page used for system
/// calls and other nice things.
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index 443638aa39f6..5463a071503c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -151,10 +151,8 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
const uint32_t msbyte = msbit / 8;
const uint32_t lsbyte = lsbit / 8;
- ConstString containing_reg_name(reg_name_str);
-
const RegisterInfo *containing_reg_info =
- GetRegisterInfo(containing_reg_name);
+ GetRegisterInfo(reg_name_str);
if (containing_reg_info) {
const uint32_t max_bit = containing_reg_info->byte_size * 8;
if (msbit < max_bit && lsbit < max_bit) {
@@ -189,7 +187,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
}
} else {
printf("error: invalid concrete register \"%s\"\n",
- containing_reg_name.GetCString());
+ reg_name_str.c_str());
}
} else {
printf("error: msbit (%u) must be greater than lsbit (%u)\n",
@@ -217,7 +215,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
if (composite_reg_list->GetItemAtIndexAsString(
composite_idx, composite_reg_name, nullptr)) {
const RegisterInfo *composite_reg_info =
- GetRegisterInfo(composite_reg_name);
+ GetRegisterInfo(composite_reg_name.GetStringRef());
if (composite_reg_info) {
composite_offset = std::min(composite_offset,
composite_reg_info->byte_offset);
@@ -357,7 +355,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
if (invalidate_reg_list->GetItemAtIndexAsString(
idx, invalidate_reg_name)) {
const RegisterInfo *invalidate_reg_info =
- GetRegisterInfo(invalidate_reg_name);
+ GetRegisterInfo(invalidate_reg_name.GetStringRef());
if (invalidate_reg_info) {
m_invalidate_regs_map[i].push_back(
invalidate_reg_info->kinds[eRegisterKindLLDB]);
@@ -430,9 +428,6 @@ void DynamicRegisterInfo::AddRegister(RegisterInfo &reg_info,
assert(set < m_set_reg_nums.size());
assert(set < m_set_names.size());
m_set_reg_nums[set].push_back(reg_num);
- size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
- if (m_reg_data_byte_size < end_reg_offset)
- m_reg_data_byte_size = end_reg_offset;
}
void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
@@ -617,8 +612,70 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
break;
}
}
+
+ // At this stage call ConfigureOffsets to calculate register offsets for
+ // targets supporting dynamic offset calculation. It also calculates
+ // total byte size of register data.
+ ConfigureOffsets();
+
+ // Check if register info is reconfigurable
+ // AArch64 SVE register set has configurable register sizes
+ if (arch.GetTriple().isAArch64()) {
+ for (const auto &reg : m_regs) {
+ if (strcmp(reg.name, "vg") == 0) {
+ m_is_reconfigurable = true;
+ break;
+ }
+ }
+ }
+}
+
+void DynamicRegisterInfo::ConfigureOffsets() {
+ // We are going to create a map between remote (eRegisterKindProcessPlugin)
+ // and local (eRegisterKindLLDB) register numbers. This map will give us
+ // remote register numbers in increasing order for offset calculation.
+ std::map<uint32_t, uint32_t> remote_to_local_regnum_map;
+ for (const auto &reg : m_regs)
+ remote_to_local_regnum_map[reg.kinds[eRegisterKindProcessPlugin]] =
+ reg.kinds[eRegisterKindLLDB];
+
+ // At this stage we manually calculate g/G packet offsets of all primary
+ // registers, only if target XML or qRegisterInfo packet did not send
+ // an offset explicitly.
+ uint32_t reg_offset = 0;
+ for (auto const &regnum_pair : remote_to_local_regnum_map) {
+ if (m_regs[regnum_pair.second].byte_offset == LLDB_INVALID_INDEX32 &&
+ m_regs[regnum_pair.second].value_regs == nullptr) {
+ m_regs[regnum_pair.second].byte_offset = reg_offset;
+
+ reg_offset = m_regs[regnum_pair.second].byte_offset +
+ m_regs[regnum_pair.second].byte_size;
+ }
+ }
+
+ // Now update all value_regs with each register info as needed
+ for (auto &reg : m_regs) {
+ if (reg.value_regs != nullptr) {
+ // Assign a valid offset to all pseudo registers if not assigned by stub.
+ // Pseudo registers with value_regs list populated will share same offset
+ // as that of their corresponding primary register in value_regs list.
+ if (reg.byte_offset == LLDB_INVALID_INDEX32) {
+ uint32_t value_regnum = reg.value_regs[0];
+ if (value_regnum != LLDB_INVALID_INDEX32)
+ reg.byte_offset =
+ GetRegisterInfoAtIndex(remote_to_local_regnum_map[value_regnum])
+ ->byte_offset;
+ }
+ }
+
+ reg_offset = reg.byte_offset + reg.byte_size;
+ if (m_reg_data_byte_size < reg_offset)
+ m_reg_data_byte_size = reg_offset;
+ }
}
+bool DynamicRegisterInfo::IsReconfigurable() { return m_is_reconfigurable; }
+
size_t DynamicRegisterInfo::GetNumRegisters() const { return m_regs.size(); }
size_t DynamicRegisterInfo::GetNumRegisterSets() const { return m_sets.size(); }
@@ -737,16 +794,10 @@ void DynamicRegisterInfo::Dump() const {
}
}
-const lldb_private::RegisterInfo *DynamicRegisterInfo::GetRegisterInfo(
- lldb_private::ConstString reg_name) const {
- for (auto &reg_info : m_regs) {
- // We can use pointer comparison since we used a ConstString to set the
- // "name" member in AddRegister()
- assert(ConstString(reg_info.name).GetCString() == reg_info.name &&
- "reg_info.name not from a ConstString?");
- if (reg_info.name == reg_name.GetCString()) {
+const lldb_private::RegisterInfo *
+DynamicRegisterInfo::GetRegisterInfo(llvm::StringRef reg_name) const {
+ for (auto &reg_info : m_regs)
+ if (reg_info.name == reg_name)
return &reg_info;
- }
- }
return nullptr;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
index 48939375a504..fbf9db685b71 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
@@ -17,6 +17,10 @@
#include "lldb/lldb-private.h"
class DynamicRegisterInfo {
+protected:
+ DynamicRegisterInfo(DynamicRegisterInfo &) = default;
+ DynamicRegisterInfo &operator=(DynamicRegisterInfo &) = default;
+
public:
DynamicRegisterInfo() = default;
@@ -25,9 +29,6 @@ public:
virtual ~DynamicRegisterInfo() = default;
- DynamicRegisterInfo(DynamicRegisterInfo &) = delete;
- void operator=(DynamicRegisterInfo &) = delete;
-
DynamicRegisterInfo(DynamicRegisterInfo &&info);
DynamicRegisterInfo &operator=(DynamicRegisterInfo &&info);
@@ -63,6 +64,11 @@ public:
void Clear();
+ bool IsReconfigurable();
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfo(llvm::StringRef reg_name) const;
+
protected:
// Classes that inherit from DynamicRegisterInfo can see and modify these
typedef std::vector<lldb_private::RegisterInfo> reg_collection;
@@ -74,11 +80,10 @@ protected:
typedef std::vector<uint8_t> dwarf_opcode;
typedef std::map<uint32_t, dwarf_opcode> dynamic_reg_size_map;
- const lldb_private::RegisterInfo *
- GetRegisterInfo(lldb_private::ConstString reg_name) const;
-
void MoveFrom(DynamicRegisterInfo &&info);
+ void ConfigureOffsets();
+
reg_collection m_regs;
set_collection m_sets;
set_reg_num_collection m_set_reg_nums;
@@ -89,5 +94,6 @@ protected:
size_t m_reg_data_byte_size = 0u; // The number of bytes required to store
// all registers
bool m_finalized = false;
+ bool m_is_reconfigurable = false;
};
#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h
new file mode 100644
index 000000000000..7f6f7cf5832d
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h
@@ -0,0 +1,291 @@
+//===-- LinuxPTraceDefines_arm64sve.h ------------------------- -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPTRACEDEFINES_ARM64SVE_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPTRACEDEFINES_ARM64SVE_H
+
+#include <stdint.h>
+
+namespace lldb_private {
+namespace sve {
+
+/*
+ * The SVE architecture leaves space for future expansion of the
+ * vector length beyond its initial architectural limit of 2048 bits
+ * (16 quadwords).
+ *
+ * See <Linux kernel source tree>/Documentation/arm64/sve.rst for a description
+ * of the vl/vq terminology.
+ */
+
+const uint16_t vq_bytes = 16; /* number of bytes per quadword */
+
+const uint16_t vq_min = 1;
+const uint16_t vq_max = 512;
+
+const uint16_t vl_min = vq_min * vq_bytes;
+const uint16_t vl_max = vq_max * vq_bytes;
+
+const uint16_t num_of_zregs = 32;
+const uint16_t num_of_pregs = 16;
+
+inline uint16_t vl_valid(uint16_t vl) {
+ return (vl % vq_bytes == 0 && vl >= vl_min && vl <= vl_max);
+}
+
+inline uint16_t vq_from_vl(uint16_t vl) { return vl / vq_bytes; }
+inline uint16_t vl_from_vq(uint16_t vq) { return vq * vq_bytes; }
+
+/* A new signal frame record sve_context encodes the SVE Registers on signal
+ * delivery. sve_context struct definition may be included in asm/sigcontext.h.
+ * We define sve_context_size which will be used by LLDB sve helper functions.
+ * More information on sve_context can be found in Linux kernel source tree at
+ * Documentation/arm64/sve.rst.
+ */
+
+const uint16_t sve_context_size = 16;
+
+/*
+ * If the SVE registers are currently live for the thread at signal delivery,
+ * sve_context.head.size >=
+ * SigContextSize(vq_from_vl(sve_context.vl))
+ * and the register data may be accessed using the Sig*() functions.
+ *
+ * If sve_context.head.size <
+ * SigContextSize(vq_from_vl(sve_context.vl)),
+ * the SVE registers were not live for the thread and no register data
+ * is included: in this case, the Sig*() functions should not be
+ * used except for this check.
+ *
+ * The same convention applies when returning from a signal: a caller
+ * will need to remove or resize the sve_context block if it wants to
+ * make the SVE registers live when they were previously non-live or
+ * vice-versa. This may require the the caller to allocate fresh
+ * memory and/or move other context blocks in the signal frame.
+ *
+ * Changing the vector length during signal return is not permitted:
+ * sve_context.vl must equal the thread's current vector length when
+ * doing a sigreturn.
+ *
+ *
+ * Note: for all these functions, the "vq" argument denotes the SVE
+ * vector length in quadwords (i.e., units of 128 bits).
+ *
+ * The correct way to obtain vq is to use vq_from_vl(vl). The
+ * result is valid if and only if vl_valid(vl) is true. This is
+ * guaranteed for a struct sve_context written by the kernel.
+ *
+ *
+ * Additional functions describe the contents and layout of the payload.
+ * For each, Sig*Offset(args) is the start offset relative to
+ * the start of struct sve_context, and Sig*Size(args) is the
+ * size in bytes:
+ *
+ * x type description
+ * - ---- -----------
+ * REGS the entire SVE context
+ *
+ * ZREGS __uint128_t[num_of_zregs][vq] all Z-registers
+ * ZREG __uint128_t[vq] individual Z-register Zn
+ *
+ * PREGS uint16_t[num_of_pregs][vq] all P-registers
+ * PREG uint16_t[vq] individual P-register Pn
+ *
+ * FFR uint16_t[vq] first-fault status register
+ *
+ * Additional data might be appended in the future.
+ */
+
+inline uint16_t SigZRegSize(uint16_t vq) { return vq * vq_bytes; }
+inline uint16_t SigPRegSize(uint16_t vq) { return vq * vq_bytes / 8; }
+inline uint16_t SigFFRSize(uint16_t vq) { return SigPRegSize(vq); }
+
+inline uint32_t SigRegsOffset() {
+ return (sve_context_size + vq_bytes - 1) / vq_bytes * vq_bytes;
+}
+
+inline uint32_t SigZRegsOffset() { return SigRegsOffset(); }
+
+inline uint32_t SigZRegOffset(uint16_t vq, uint16_t n) {
+ return SigRegsOffset() + SigZRegSize(vq) * n;
+}
+
+inline uint32_t SigZRegsSize(uint16_t vq) {
+ return SigZRegOffset(vq, num_of_zregs) - SigRegsOffset();
+}
+
+inline uint32_t SigPRegsOffset(uint16_t vq) {
+ return SigRegsOffset() + SigZRegsSize(vq);
+}
+
+inline uint32_t SigPRegOffset(uint16_t vq, uint16_t n) {
+ return SigPRegsOffset(vq) + SigPRegSize(vq) * n;
+}
+
+inline uint32_t SigpRegsSize(uint16_t vq) {
+ return SigPRegOffset(vq, num_of_pregs) - SigPRegsOffset(vq);
+}
+
+inline uint32_t SigFFROffset(uint16_t vq) {
+ return SigPRegsOffset(vq) + SigpRegsSize(vq);
+}
+
+inline uint32_t SigRegsSize(uint16_t vq) {
+ return SigFFROffset(vq) + SigFFRSize(vq) - SigRegsOffset();
+}
+
+inline uint32_t SVESigContextSize(uint16_t vq) {
+ return SigRegsOffset() + SigRegsSize(vq);
+}
+
+struct user_sve_header {
+ uint32_t size; /* total meaningful regset content in bytes */
+ uint32_t max_size; /* maxmium possible size for this thread */
+ uint16_t vl; /* current vector length */
+ uint16_t max_vl; /* maximum possible vector length */
+ uint16_t flags;
+ uint16_t reserved;
+};
+
+/* Definitions for user_sve_header.flags: */
+const uint16_t ptrace_regs_mask = 1 << 0;
+const uint16_t ptrace_regs_fpsimd = 0;
+const uint16_t ptrace_regs_sve = ptrace_regs_mask;
+
+/*
+ * The remainder of the SVE state follows struct user_sve_header. The
+ * total size of the SVE state (including header) depends on the
+ * metadata in the header: PTraceSize(vq, flags) gives the total size
+ * of the state in bytes, including the header.
+ *
+ * Refer to <asm/sigcontext.h> for details of how to pass the correct
+ * "vq" argument to these macros.
+ */
+
+/* Offset from the start of struct user_sve_header to the register data */
+inline uint16_t PTraceRegsOffset() {
+ return (sizeof(struct user_sve_header) + vq_bytes - 1) / vq_bytes * vq_bytes;
+}
+
+/*
+ * The register data content and layout depends on the value of the
+ * flags field.
+ */
+
+/*
+ * (flags & ptrace_regs_mask) == ptrace_regs_fpsimd case:
+ *
+ * The payload starts at offset PTraceFPSIMDOffset, and is of type
+ * struct user_fpsimd_state. Additional data might be appended in the
+ * future: use PTraceFPSIMDSize(vq, flags) to compute the total size.
+ * PTraceFPSIMDSize(vq, flags) will never be less than
+ * sizeof(struct user_fpsimd_state).
+ */
+
+const uint32_t ptrace_fpsimd_offset = PTraceRegsOffset();
+
+/* Return size of struct user_fpsimd_state from asm/ptrace.h */
+inline uint32_t PTraceFPSIMDSize(uint16_t vq, uint16_t flags) { return 528; }
+
+/*
+ * (flags & ptrace_regs_mask) == ptrace_regs_sve case:
+ *
+ * The payload starts at offset PTraceSVEOffset, and is of size
+ * PTraceSVESize(vq, flags).
+ *
+ * Additional functions describe the contents and layout of the payload.
+ * For each, PTrace*X*Offset(args) is the start offset relative to
+ * the start of struct user_sve_header, and PTrace*X*Size(args) is
+ * the size in bytes:
+ *
+ * x type description
+ * - ---- -----------
+ * ZREGS \
+ * ZREG |
+ * PREGS | refer to <asm/sigcontext.h>
+ * PREG |
+ * FFR /
+ *
+ * FPSR uint32_t FPSR
+ * FPCR uint32_t FPCR
+ *
+ * Additional data might be appended in the future.
+ */
+
+inline uint32_t PTraceZRegSize(uint16_t vq) { return SigZRegSize(vq); }
+
+inline uint32_t PTracePRegSize(uint16_t vq) { return SigPRegSize(vq); }
+
+inline uint32_t PTraceFFRSize(uint16_t vq) { return SigFFRSize(vq); }
+
+const uint32_t fpsr_size = sizeof(uint32_t);
+const uint32_t fpcr_size = sizeof(uint32_t);
+
+inline uint32_t SigToPTrace(uint32_t offset) {
+ return offset - SigRegsOffset() + PTraceRegsOffset();
+}
+
+const uint32_t ptrace_sve_offset = PTraceRegsOffset();
+
+inline uint32_t PTraceZRegsOffset(uint16_t vq) {
+ return SigToPTrace(SigZRegsOffset());
+}
+
+inline uint32_t PTraceZRegOffset(uint16_t vq, uint16_t n) {
+ return SigToPTrace(SigZRegOffset(vq, n));
+}
+
+inline uint32_t PTraceZRegsSize(uint16_t vq) {
+ return PTraceZRegOffset(vq, num_of_zregs) - SigToPTrace(SigRegsOffset());
+}
+
+inline uint32_t PTracePRegsOffset(uint16_t vq) {
+ return SigToPTrace(SigPRegsOffset(vq));
+}
+
+inline uint32_t PTracePRegOffset(uint16_t vq, uint16_t n) {
+ return SigToPTrace(SigPRegOffset(vq, n));
+}
+
+inline uint32_t PTracePRegsSize(uint16_t vq) {
+ return PTracePRegOffset(vq, num_of_pregs) - PTracePRegsOffset(vq);
+}
+
+inline uint32_t PTraceFFROffset(uint16_t vq) {
+ return SigToPTrace(SigFFROffset(vq));
+}
+
+inline uint32_t PTraceFPSROffset(uint16_t vq) {
+ return (PTraceFFROffset(vq) + PTraceFFRSize(vq) + (vq_bytes - 1)) / vq_bytes *
+ vq_bytes;
+}
+
+inline uint32_t PTraceFPCROffset(uint16_t vq) {
+ return PTraceFPSROffset(vq) + fpsr_size;
+}
+
+/*
+ * Any future extension appended after FPCR must be aligned to the next
+ * 128-bit boundary.
+ */
+
+inline uint32_t PTraceSVESize(uint16_t vq, uint16_t flags) {
+ return (PTraceFPCROffset(vq) + fpcr_size - ptrace_sve_offset + vq_bytes - 1) /
+ vq_bytes * vq_bytes;
+}
+
+inline uint32_t PTraceSize(uint16_t vq, uint16_t flags) {
+ return (flags & ptrace_regs_mask) == ptrace_regs_sve
+ ? ptrace_sve_offset + PTraceSVESize(vq, flags)
+ : ptrace_fpsimd_offset + PTraceFPSIMDSize(vq, flags);
+}
+
+} // namespace SVE
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPTRACEDEFINES_ARM64SVE_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp
index 0c7d9ddc5ac6..947b970edf6c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp
@@ -7,80 +7,93 @@
//===----------------------------------------------------------------------===//
#include "LinuxProcMaps.h"
-#include "llvm/ADT/StringRef.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StringExtractor.h"
+#include "llvm/ADT/StringRef.h"
using namespace lldb_private;
-static Status
+enum class MapsKind { Maps, SMaps };
+
+static llvm::Expected<MemoryRegionInfo> ProcMapError(const char *msg,
+ MapsKind kind) {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(), msg,
+ kind == MapsKind::Maps ? "maps" : "smaps");
+}
+
+static llvm::Expected<MemoryRegionInfo>
ParseMemoryRegionInfoFromProcMapsLine(llvm::StringRef maps_line,
- MemoryRegionInfo &memory_region_info) {
- memory_region_info.Clear();
-
+ MapsKind maps_kind) {
+ MemoryRegionInfo region;
StringExtractor line_extractor(maps_line);
-
+
// Format: {address_start_hex}-{address_end_hex} perms offset dev inode
// pathname perms: rwxp (letter is present if set, '-' if not, final
// character is p=private, s=shared).
-
+
// Parse out the starting address
lldb::addr_t start_address = line_extractor.GetHexMaxU64(false, 0);
-
+
// Parse out hyphen separating start and end address from range.
if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != '-'))
- return Status(
- "malformed /proc/{pid}/maps entry, missing dash between address range");
-
+ return ProcMapError(
+ "malformed /proc/{pid}/%s entry, missing dash between address range",
+ maps_kind);
+
// Parse out the ending address
lldb::addr_t end_address = line_extractor.GetHexMaxU64(false, start_address);
-
+
// Parse out the space after the address.
if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != ' '))
- return Status(
- "malformed /proc/{pid}/maps entry, missing space after range");
-
+ return ProcMapError(
+ "malformed /proc/{pid}/%s entry, missing space after range", maps_kind);
+
// Save the range.
- 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);
-
+ region.GetRange().SetRangeBase(start_address);
+ region.GetRange().SetRangeEnd(end_address);
+
+ // Any memory region in /proc/{pid}/(maps|smaps) is by definition mapped
+ // into the process.
+ region.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
+
// Parse out each permission entry.
if (line_extractor.GetBytesLeft() < 4)
- return Status("malformed /proc/{pid}/maps entry, missing some portion of "
- "permissions");
-
+ return ProcMapError(
+ "malformed /proc/{pid}/%s entry, missing some portion of "
+ "permissions",
+ maps_kind);
+
// Handle read permission.
const char read_perm_char = line_extractor.GetChar();
if (read_perm_char == 'r')
- memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eYes);
+ region.SetReadable(MemoryRegionInfo::OptionalBool::eYes);
else if (read_perm_char == '-')
- memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
+ region.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
else
- return Status("unexpected /proc/{pid}/maps read permission char");
-
+ return ProcMapError("unexpected /proc/{pid}/%s read permission char",
+ maps_kind);
+
// Handle write permission.
const char write_perm_char = line_extractor.GetChar();
if (write_perm_char == 'w')
- memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eYes);
+ region.SetWritable(MemoryRegionInfo::OptionalBool::eYes);
else if (write_perm_char == '-')
- memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
+ region.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
else
- return Status("unexpected /proc/{pid}/maps write permission char");
-
+ return ProcMapError("unexpected /proc/{pid}/%s write permission char",
+ maps_kind);
+
// Handle execute permission.
const char exec_perm_char = line_extractor.GetChar();
if (exec_perm_char == 'x')
- memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes);
+ region.SetExecutable(MemoryRegionInfo::OptionalBool::eYes);
else if (exec_perm_char == '-')
- memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
+ region.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
else
- return Status("unexpected /proc/{pid}/maps exec permission char");
-
+ return ProcMapError("unexpected /proc/{pid}/%s exec permission char",
+ maps_kind);
+
line_extractor.GetChar(); // Read the private bit
line_extractor.SkipSpaces(); // Skip the separator
line_extractor.GetHexMaxU64(false, 0); // Read the offset
@@ -89,13 +102,13 @@ ParseMemoryRegionInfoFromProcMapsLine(llvm::StringRef maps_line,
line_extractor.GetHexMaxU64(false, 0); // Read the major device number
line_extractor.SkipSpaces(); // Skip the separator
line_extractor.GetU64(0, 10); // Read the inode number
-
+
line_extractor.SkipSpaces();
const char *name = line_extractor.Peek();
if (name)
- memory_region_info.SetName(name);
-
- return Status();
+ region.SetName(name);
+
+ return region;
}
void lldb_private::ParseLinuxMapRegions(llvm::StringRef linux_map,
@@ -104,9 +117,80 @@ void lldb_private::ParseLinuxMapRegions(llvm::StringRef linux_map,
llvm::StringRef line;
while (!lines.empty()) {
std::tie(line, lines) = lines.split('\n');
- MemoryRegionInfo region;
- Status error = ParseMemoryRegionInfoFromProcMapsLine(line, region);
- if (!callback(region, error))
+ if (!callback(ParseMemoryRegionInfoFromProcMapsLine(line, MapsKind::Maps)))
break;
}
}
+
+void lldb_private::ParseLinuxSMapRegions(llvm::StringRef linux_smap,
+ LinuxMapCallback const &callback) {
+ // Entries in /smaps look like:
+ // 00400000-0048a000 r-xp 00000000 fd:03 960637
+ // Size: 552 kB
+ // Rss: 460 kB
+ // <...>
+ // VmFlags: rd ex mr mw me dw
+ // 00500000-0058a000 rwxp 00000000 fd:03 960637
+ // <...>
+ //
+ // Where the first line is identical to the /maps format
+ // and VmFlags is only printed for kernels >= 3.8.
+
+ llvm::StringRef lines(linux_smap);
+ llvm::StringRef line;
+ llvm::Optional<MemoryRegionInfo> region;
+
+ while (lines.size()) {
+ std::tie(line, lines) = lines.split('\n');
+
+ // A property line looks like:
+ // <word>: <value>
+ // (no spaces on the left hand side)
+ // A header will have a ':' but the LHS will contain spaces
+ llvm::StringRef name;
+ llvm::StringRef value;
+ std::tie(name, value) = line.split(':');
+
+ // If this line is a property line
+ if (!name.contains(' ')) {
+ if (region) {
+ if (name == "VmFlags") {
+ if (value.contains("mt"))
+ region->SetMemoryTagged(MemoryRegionInfo::eYes);
+ else
+ region->SetMemoryTagged(MemoryRegionInfo::eNo);
+ }
+ // Ignore anything else
+ } else {
+ // Orphaned settings line
+ callback(ProcMapError(
+ "Found a property line without a corresponding mapping "
+ "in /proc/{pid}/%s",
+ MapsKind::SMaps));
+ return;
+ }
+ } else {
+ // Must be a new region header
+ if (region) {
+ // Save current region
+ callback(*region);
+ region.reset();
+ }
+
+ // Try to start a new region
+ llvm::Expected<MemoryRegionInfo> new_region =
+ ParseMemoryRegionInfoFromProcMapsLine(line, MapsKind::SMaps);
+ if (new_region) {
+ region = *new_region;
+ } else {
+ // Stop at first invalid region header
+ callback(new_region.takeError());
+ return;
+ }
+ }
+ }
+
+ // Catch last region
+ if (region)
+ callback(*region);
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h
index 363f248fd416..02f78d55c290 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h
@@ -11,16 +11,16 @@
#include "lldb/lldb-forward.h"
#include "llvm/ADT/StringRef.h"
-#include <functional>
-
+#include "llvm/Support/Error.h"
namespace lldb_private {
-typedef std::function<bool(const lldb_private::MemoryRegionInfo &,
- const lldb_private::Status &)> LinuxMapCallback;
+typedef std::function<bool(llvm::Expected<MemoryRegionInfo>)> LinuxMapCallback;
void ParseLinuxMapRegions(llvm::StringRef linux_map,
LinuxMapCallback const &callback);
+void ParseLinuxSMapRegions(llvm::StringRef linux_smap,
+ LinuxMapCallback const &callback);
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp
index 4dd619e3bade..d4b0f4039da9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp
@@ -14,79 +14,72 @@ LinuxSignals::LinuxSignals() : UnixSignals() { Reset(); }
void LinuxSignals::Reset() {
m_signals.clear();
- // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION ALIAS
- // ===== =========== ======== ===== ======
- // ====================================== ======
- AddSignal(1, "SIGHUP", false, true, true, "hangup");
- AddSignal(2, "SIGINT", true, true, true, "interrupt");
- AddSignal(3, "SIGQUIT", false, true, true, "quit");
- AddSignal(4, "SIGILL", false, true, true, "illegal instruction");
- AddSignal(5, "SIGTRAP", true, true, true,
- "trace trap (not reset when caught)");
- AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT");
- AddSignal(7, "SIGBUS", false, true, true, "bus error");
- AddSignal(8, "SIGFPE", false, true, true, "floating point exception");
- AddSignal(9, "SIGKILL", false, true, true, "kill");
- AddSignal(10, "SIGUSR1", false, true, true, "user defined signal 1");
- AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation");
- AddSignal(12, "SIGUSR2", false, true, true, "user defined signal 2");
- AddSignal(13, "SIGPIPE", false, true, true,
- "write to pipe with reading end closed");
- AddSignal(14, "SIGALRM", false, false, false, "alarm");
- AddSignal(15, "SIGTERM", false, true, true, "termination requested");
- AddSignal(16, "SIGSTKFLT", false, true, true, "stack fault");
- AddSignal(17, "SIGCHLD", false, false, true, "child status has changed",
- "SIGCLD");
- AddSignal(18, "SIGCONT", false, true, true, "process continue");
- AddSignal(19, "SIGSTOP", true, true, true, "process stop");
- AddSignal(20, "SIGTSTP", false, true, true, "tty stop");
- AddSignal(21, "SIGTTIN", false, true, true, "background tty read");
- AddSignal(22, "SIGTTOU", false, true, true, "background tty write");
- AddSignal(23, "SIGURG", false, true, true, "urgent data on socket");
- AddSignal(24, "SIGXCPU", false, true, true, "CPU resource exceeded");
- AddSignal(25, "SIGXFSZ", false, true, true, "file size limit exceeded");
- AddSignal(26, "SIGVTALRM", false, true, true, "virtual time alarm");
- AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm");
- AddSignal(28, "SIGWINCH", false, true, true, "window size changes");
- AddSignal(29, "SIGIO", false, true, true, "input/output ready/Pollable event",
- "SIGPOLL");
- AddSignal(30, "SIGPWR", false, true, true, "power failure");
- AddSignal(31, "SIGSYS", false, true, true, "invalid system call");
- AddSignal(32, "SIG32", false, false, false,
- "threading library internal signal 1");
- AddSignal(33, "SIG33", false, false, false,
- "threading library internal signal 2");
- AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0");
- AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1");
- AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2");
- AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3");
- AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4");
- AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5");
- AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6");
- AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7");
- AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8");
- AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9");
- AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10");
- AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11");
- AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12");
- AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13");
- AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14");
- AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15");
- AddSignal(50, "SIGRTMAX-14", false, false, false,
- "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill
- // -l" output
- AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17");
- AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18");
- AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19");
- AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20");
- AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21");
- AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22");
- AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23");
- AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24");
- AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25");
- AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26");
- AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27");
- AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28");
- AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29");
- AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30");
+ // clang-format off
+ // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION
+ // ====== ============== ======== ====== ====== ===================================================
+ AddSignal(1, "SIGHUP", false, true, true, "hangup");
+ AddSignal(2, "SIGINT", true, true, true, "interrupt");
+ AddSignal(3, "SIGQUIT", false, true, true, "quit");
+ AddSignal(4, "SIGILL", false, true, true, "illegal instruction");
+ AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)");
+ AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT");
+ AddSignal(7, "SIGBUS", false, true, true, "bus error");
+ AddSignal(8, "SIGFPE", false, true, true, "floating point exception");
+ AddSignal(9, "SIGKILL", false, true, true, "kill");
+ AddSignal(10, "SIGUSR1", false, true, true, "user defined signal 1");
+ AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation");
+ AddSignal(12, "SIGUSR2", false, true, true, "user defined signal 2");
+ AddSignal(13, "SIGPIPE", false, true, true, "write to pipe with reading end closed");
+ AddSignal(14, "SIGALRM", false, false, false, "alarm");
+ AddSignal(15, "SIGTERM", false, true, true, "termination requested");
+ AddSignal(16, "SIGSTKFLT", false, true, true, "stack fault");
+ AddSignal(17, "SIGCHLD", false, false, true, "child status has changed", "SIGCLD");
+ AddSignal(18, "SIGCONT", false, false, true, "process continue");
+ AddSignal(19, "SIGSTOP", true, true, true, "process stop");
+ AddSignal(20, "SIGTSTP", false, true, true, "tty stop");
+ AddSignal(21, "SIGTTIN", false, true, true, "background tty read");
+ AddSignal(22, "SIGTTOU", false, true, true, "background tty write");
+ AddSignal(23, "SIGURG", false, true, true, "urgent data on socket");
+ AddSignal(24, "SIGXCPU", false, true, true, "CPU resource exceeded");
+ AddSignal(25, "SIGXFSZ", false, true, true, "file size limit exceeded");
+ AddSignal(26, "SIGVTALRM", false, true, true, "virtual time alarm");
+ AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm");
+ AddSignal(28, "SIGWINCH", false, true, true, "window size changes");
+ AddSignal(29, "SIGIO", false, true, true, "input/output ready/Pollable event", "SIGPOLL");
+ AddSignal(30, "SIGPWR", false, true, true, "power failure");
+ AddSignal(31, "SIGSYS", false, true, true, "invalid system call");
+ AddSignal(32, "SIG32", false, false, false, "threading library internal signal 1");
+ AddSignal(33, "SIG33", false, false, false, "threading library internal signal 2");
+ AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0");
+ AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1");
+ AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2");
+ AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3");
+ AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4");
+ AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5");
+ AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6");
+ AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7");
+ AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8");
+ AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9");
+ AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10");
+ AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11");
+ AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12");
+ AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13");
+ AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14");
+ AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15");
+ AddSignal(50, "SIGRTMAX-14", false, false, false, "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill -l" output
+ AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17");
+ AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18");
+ AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19");
+ AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20");
+ AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21");
+ AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22");
+ AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23");
+ AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24");
+ AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25");
+ AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26");
+ AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27");
+ AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28");
+ AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29");
+ AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30");
+ // clang-format on
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
index 8f75844277c0..fb51c56953f8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
@@ -14,79 +14,72 @@ MipsLinuxSignals::MipsLinuxSignals() : UnixSignals() { Reset(); }
void MipsLinuxSignals::Reset() {
m_signals.clear();
- // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION ALIAS
- // ===== =========== ======== ===== ======
- // ====================================== ========
- AddSignal(1, "SIGHUP", false, true, true, "hangup");
- AddSignal(2, "SIGINT", true, true, true, "interrupt");
- AddSignal(3, "SIGQUIT", false, true, true, "quit");
- AddSignal(4, "SIGILL", false, true, true, "illegal instruction");
- AddSignal(5, "SIGTRAP", true, true, true,
- "trace trap (not reset when caught)");
- AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT");
- AddSignal(7, "SIGEMT", false, true, true, "terminate process with core dump");
- AddSignal(8, "SIGFPE", false, true, true, "floating point exception");
- AddSignal(9, "SIGKILL", false, true, true, "kill");
- AddSignal(10, "SIGBUS", false, true, true, "bus error");
- AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation");
- AddSignal(12, "SIGSYS", false, true, true, "invalid system call");
- AddSignal(13, "SIGPIPE", false, true, true,
- "write to pipe with reading end closed");
- AddSignal(14, "SIGALRM", false, false, false, "alarm");
- AddSignal(15, "SIGTERM", false, true, true, "termination requested");
- AddSignal(16, "SIGUSR1", false, true, true, "user defined signal 1");
- AddSignal(17, "SIGUSR2", false, true, true, "user defined signal 2");
- AddSignal(18, "SIGCHLD", false, false, true, "child status has changed",
- "SIGCLD");
- AddSignal(19, "SIGPWR", false, true, true, "power failure");
- AddSignal(20, "SIGWINCH", false, true, true, "window size changes");
- AddSignal(21, "SIGURG", false, true, true, "urgent data on socket");
- AddSignal(22, "SIGIO", false, true, true, "input/output ready/Pollable event",
- "SIGPOLL");
- AddSignal(23, "SIGSTOP", true, true, true, "process stop");
- AddSignal(24, "SIGTSTP", false, true, true, "tty stop");
- AddSignal(25, "SIGCONT", false, true, true, "process continue");
- AddSignal(26, "SIGTTIN", false, true, true, "background tty read");
- AddSignal(27, "SIGTTOU", false, true, true, "background tty write");
- AddSignal(28, "SIGVTALRM", false, true, true, "virtual time alarm");
- AddSignal(29, "SIGPROF", false, false, false, "profiling time alarm");
- AddSignal(30, "SIGXCPU", false, true, true, "CPU resource exceeded");
- AddSignal(31, "SIGXFSZ", false, true, true, "file size limit exceeded");
- AddSignal(32, "SIG32", false, false, false,
- "threading library internal signal 1");
- AddSignal(33, "SIG33", false, false, false,
- "threading library internal signal 2");
- AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0");
- AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1");
- AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2");
- AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3");
- AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4");
- AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5");
- AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6");
- AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7");
- AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8");
- AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9");
- AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10");
- AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11");
- AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12");
- AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13");
- AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14");
- AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15");
- AddSignal(50, "SIGRTMAX-14", false, false, false,
- "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill
- // -l" output
- AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17");
- AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18");
- AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19");
- AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20");
- AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21");
- AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22");
- AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23");
- AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24");
- AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25");
- AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26");
- AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27");
- AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28");
- AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29");
- AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30");
+ // clang-format off
+ // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION
+ // ====== ============== ======== ====== ====== ===================================================
+ AddSignal(1, "SIGHUP", false, true, true, "hangup");
+ AddSignal(2, "SIGINT", true, true, true, "interrupt");
+ AddSignal(3, "SIGQUIT", false, true, true, "quit");
+ AddSignal(4, "SIGILL", false, true, true, "illegal instruction");
+ AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)");
+ AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT");
+ AddSignal(7, "SIGEMT", false, true, true, "terminate process with core dump");
+ AddSignal(8, "SIGFPE", false, true, true, "floating point exception");
+ AddSignal(9, "SIGKILL", false, true, true, "kill");
+ AddSignal(10, "SIGBUS", false, true, true, "bus error");
+ AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation");
+ AddSignal(12, "SIGSYS", false, true, true, "invalid system call");
+ AddSignal(13, "SIGPIPE", false, true, true, "write to pipe with reading end closed");
+ AddSignal(14, "SIGALRM", false, false, false, "alarm");
+ AddSignal(15, "SIGTERM", false, true, true, "termination requested");
+ AddSignal(16, "SIGUSR1", false, true, true, "user defined signal 1");
+ AddSignal(17, "SIGUSR2", false, true, true, "user defined signal 2");
+ AddSignal(18, "SIGCHLD", false, false, true, "child status has changed", "SIGCLD");
+ AddSignal(19, "SIGPWR", false, true, true, "power failure");
+ AddSignal(20, "SIGWINCH", false, true, true, "window size changes");
+ AddSignal(21, "SIGURG", false, true, true, "urgent data on socket");
+ AddSignal(22, "SIGIO", false, true, true, "input/output ready/Pollable event", "SIGPOLL");
+ AddSignal(23, "SIGSTOP", true, true, true, "process stop");
+ AddSignal(24, "SIGTSTP", false, true, true, "tty stop");
+ AddSignal(25, "SIGCONT", false, false, true, "process continue");
+ AddSignal(26, "SIGTTIN", false, true, true, "background tty read");
+ AddSignal(27, "SIGTTOU", false, true, true, "background tty write");
+ AddSignal(28, "SIGVTALRM", false, true, true, "virtual time alarm");
+ AddSignal(29, "SIGPROF", false, false, false, "profiling time alarm");
+ AddSignal(30, "SIGXCPU", false, true, true, "CPU resource exceeded");
+ AddSignal(31, "SIGXFSZ", false, true, true, "file size limit exceeded");
+ AddSignal(32, "SIG32", false, false, false, "threading library internal signal 1");
+ AddSignal(33, "SIG33", false, false, false, "threading library internal signal 2");
+ AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0");
+ AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1");
+ AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2");
+ AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3");
+ AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4");
+ AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5");
+ AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6");
+ AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7");
+ AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8");
+ AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9");
+ AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10");
+ AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11");
+ AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12");
+ AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13");
+ AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14");
+ AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15");
+ AddSignal(50, "SIGRTMAX-14", false, false, false, "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill -l" output
+ AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17");
+ AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18");
+ AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19");
+ AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20");
+ AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21");
+ AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22");
+ AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23");
+ AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24");
+ AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25");
+ AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26");
+ AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27");
+ AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28");
+ AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29");
+ AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30");
+ // clang-format on
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp
new file mode 100644
index 000000000000..ee5295bf6565
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp
@@ -0,0 +1,182 @@
+//===-- NativeProcessSoftwareSingleStep.cpp -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeProcessSoftwareSingleStep.h"
+
+#include "lldb/Core/EmulateInstruction.h"
+#include "lldb/Host/common/NativeRegisterContext.h"
+#include "lldb/Utility/RegisterValue.h"
+
+#include <unordered_map>
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+
+struct EmulatorBaton {
+ NativeProcessProtocol &m_process;
+ NativeRegisterContext &m_reg_context;
+
+ // eRegisterKindDWARF -> RegsiterValue
+ std::unordered_map<uint32_t, RegisterValue> m_register_values;
+
+ EmulatorBaton(NativeProcessProtocol &process,
+ NativeRegisterContext &reg_context)
+ : m_process(process), m_reg_context(reg_context) {}
+};
+
+} // anonymous namespace
+
+static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr, void *dst, size_t length) {
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
+
+ size_t bytes_read;
+ emulator_baton->m_process.ReadMemory(addr, dst, length, bytes_read);
+ return bytes_read;
+}
+
+static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
+
+ auto it = emulator_baton->m_register_values.find(
+ reg_info->kinds[eRegisterKindDWARF]);
+ if (it != emulator_baton->m_register_values.end()) {
+ reg_value = it->second;
+ return true;
+ }
+
+ // The emulator only fill in the dwarf regsiter numbers (and in some case the
+ // generic register numbers). Get the full register info from the register
+ // context based on the dwarf register numbers.
+ const RegisterInfo *full_reg_info =
+ emulator_baton->m_reg_context.GetRegisterInfo(
+ eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]);
+
+ Status error =
+ emulator_baton->m_reg_context.ReadRegister(full_reg_info, reg_value);
+ if (error.Success())
+ return true;
+
+ return false;
+}
+
+static bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) {
+ EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
+ emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] =
+ reg_value;
+ return true;
+}
+
+static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr, const void *dst,
+ size_t length) {
+ return length;
+}
+
+static lldb::addr_t ReadFlags(NativeRegisterContext &regsiter_context) {
+ const RegisterInfo *flags_info = regsiter_context.GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+ return regsiter_context.ReadRegisterAsUnsigned(flags_info,
+ LLDB_INVALID_ADDRESS);
+}
+
+Status NativeProcessSoftwareSingleStep::SetupSoftwareSingleStepping(
+ NativeThreadProtocol &thread) {
+ Status error;
+ NativeProcessProtocol &process = thread.GetProcess();
+ NativeRegisterContext &register_context = thread.GetRegisterContext();
+ const ArchSpec &arch = process.GetArchitecture();
+
+ std::unique_ptr<EmulateInstruction> emulator_up(
+ EmulateInstruction::FindPlugin(arch, eInstructionTypePCModifying,
+ nullptr));
+
+ if (emulator_up == nullptr)
+ return Status("Instruction emulator not found!");
+
+ EmulatorBaton baton(process, register_context);
+ emulator_up->SetBaton(&baton);
+ emulator_up->SetReadMemCallback(&ReadMemoryCallback);
+ emulator_up->SetReadRegCallback(&ReadRegisterCallback);
+ emulator_up->SetWriteMemCallback(&WriteMemoryCallback);
+ emulator_up->SetWriteRegCallback(&WriteRegisterCallback);
+
+ if (!emulator_up->ReadInstruction())
+ return Status("Read instruction failed!");
+
+ bool emulation_result =
+ emulator_up->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
+
+ const RegisterInfo *reg_info_pc = register_context.GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+ const RegisterInfo *reg_info_flags = register_context.GetRegisterInfo(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+
+ auto pc_it =
+ baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]);
+ auto flags_it =
+ baton.m_register_values.find(reg_info_flags->kinds[eRegisterKindDWARF]);
+
+ lldb::addr_t next_pc;
+ lldb::addr_t next_flags;
+ if (emulation_result) {
+ assert(pc_it != baton.m_register_values.end() &&
+ "Emulation was successfull but PC wasn't updated");
+ next_pc = pc_it->second.GetAsUInt64();
+
+ if (flags_it != baton.m_register_values.end())
+ next_flags = flags_it->second.GetAsUInt64();
+ else
+ next_flags = ReadFlags(register_context);
+ } else if (pc_it == baton.m_register_values.end()) {
+ // Emulate instruction failed and it haven't changed PC. Advance PC with
+ // the size of the current opcode because the emulation of all
+ // PC modifying instruction should be successful. The failure most
+ // likely caused by a not supported instruction which don't modify PC.
+ next_pc = register_context.GetPC() + emulator_up->GetOpcode().GetByteSize();
+ next_flags = ReadFlags(register_context);
+ } else {
+ // The instruction emulation failed after it modified the PC. It is an
+ // unknown error where we can't continue because the next instruction is
+ // modifying the PC but we don't know how.
+ return Status("Instruction emulation failed unexpectedly.");
+ }
+
+ int size_hint = 0;
+ if (arch.GetMachine() == llvm::Triple::arm) {
+ if (next_flags & 0x20) {
+ // Thumb mode
+ size_hint = 2;
+ } else {
+ // Arm mode
+ size_hint = 4;
+ }
+ } else if (arch.IsMIPS() || arch.GetTriple().isPPC64())
+ size_hint = 4;
+ error = process.SetBreakpoint(next_pc, size_hint, /*hardware=*/false);
+
+ // If setting the breakpoint fails because next_pc is out of the address
+ // space, ignore it and let the debugee segfault.
+ if (error.GetError() == EIO || error.GetError() == EFAULT) {
+ return Status();
+ } else if (error.Fail())
+ return error;
+
+ m_threads_stepping_with_breakpoint.insert({thread.GetID(), next_pc});
+
+ return Status();
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h
new file mode 100644
index 000000000000..f9435b7a84ba
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h
@@ -0,0 +1,31 @@
+//===-- NativeProcessSoftwareSingleStep.h -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_NativeProcessSoftwareSingleStep_h
+#define lldb_NativeProcessSoftwareSingleStep_h
+
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Host/common/NativeThreadProtocol.h"
+
+#include <map>
+
+namespace lldb_private {
+
+class NativeProcessSoftwareSingleStep {
+public:
+ Status SetupSoftwareSingleStepping(NativeThreadProtocol &thread);
+
+protected:
+ // List of thread ids stepping with a breakpoint with the address of
+ // the relevan breakpoint
+ std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint;
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeProcessSoftwareSingleStep_h
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp
new file mode 100644
index 000000000000..5c05baf71764
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp
@@ -0,0 +1,466 @@
+//===-- NativeRegisterContextDBReg_arm64.cpp ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeRegisterContextDBReg_arm64.h"
+
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+
+using namespace lldb_private;
+
+// E (bit 0), used to enable breakpoint/watchpoint
+constexpr uint32_t g_enable_bit = 1;
+// PAC (bits 2:1): 0b10
+constexpr uint32_t g_pac_bits = (2 << 1);
+
+// Returns appropriate control register bits for the specified size
+static constexpr inline uint64_t GetSizeBits(int size) {
+ // BAS (bits 12:5) hold a bit-mask of addresses to watch
+ // e.g. 0b00000001 means 1 byte at address
+ // 0b00000011 means 2 bytes (addr..addr+1)
+ // ...
+ // 0b11111111 means 8 bytes (addr..addr+7)
+ return ((1 << size) - 1) << 5;
+}
+
+uint32_t NativeRegisterContextDBReg_arm64::NumSupportedHardwareBreakpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error) {
+ LLDB_LOG_ERROR(log, std::move(error),
+ "failed to read debug registers: {0}");
+ return 0;
+ }
+
+ return m_max_hbp_supported;
+}
+
+uint32_t
+NativeRegisterContextDBReg_arm64::SetHardwareBreakpoint(lldb::addr_t addr,
+ size_t size) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ LLDB_LOG(log, "addr: {0:x}, size: {1:x}", addr, size);
+
+ // Read hardware breakpoint and watchpoint information.
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error) {
+ LLDB_LOG_ERROR(
+ log, std::move(error),
+ "unable to set breakpoint: failed to read debug registers: {0}");
+ return LLDB_INVALID_INDEX32;
+ }
+
+ uint32_t control_value = 0, bp_index = 0;
+
+ // Check if size has a valid hardware breakpoint length.
+ if (size != 4)
+ return LLDB_INVALID_INDEX32; // Invalid size for a AArch64 hardware
+ // breakpoint
+
+ // Check 4-byte alignment for hardware breakpoint target address.
+ if (addr & 0x03)
+ return LLDB_INVALID_INDEX32; // Invalid address, should be 4-byte aligned.
+
+ // Setup control value
+ control_value = g_enable_bit | g_pac_bits | GetSizeBits(size);
+
+ // Iterate over stored breakpoints and find a free bp_index
+ bp_index = LLDB_INVALID_INDEX32;
+ for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
+ if (!BreakpointIsEnabled(i))
+ bp_index = i; // Mark last free slot
+ else if (m_hbp_regs[i].address == addr)
+ return LLDB_INVALID_INDEX32; // We do not support duplicate breakpoints.
+ }
+
+ if (bp_index == LLDB_INVALID_INDEX32)
+ return LLDB_INVALID_INDEX32;
+
+ // Update breakpoint in local cache
+ m_hbp_regs[bp_index].real_addr = addr;
+ m_hbp_regs[bp_index].address = addr;
+ m_hbp_regs[bp_index].control = control_value;
+
+ // PTRACE call to set corresponding hardware breakpoint register.
+ error = WriteHardwareDebugRegs(eDREGTypeBREAK);
+
+ if (error) {
+ m_hbp_regs[bp_index].address = 0;
+ m_hbp_regs[bp_index].control &= ~1;
+
+ LLDB_LOG_ERROR(
+ log, std::move(error),
+ "unable to set breakpoint: failed to write debug registers: {0}");
+ return LLDB_INVALID_INDEX32;
+ }
+
+ return bp_index;
+}
+
+bool NativeRegisterContextDBReg_arm64::ClearHardwareBreakpoint(
+ uint32_t hw_idx) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ LLDB_LOG(log, "hw_idx: {0}", hw_idx);
+
+ // Read hardware breakpoint and watchpoint information.
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error) {
+ LLDB_LOG_ERROR(
+ log, std::move(error),
+ "unable to clear breakpoint: failed to read debug registers: {0}");
+ return false;
+ }
+
+ if (hw_idx >= m_max_hbp_supported)
+ return false;
+
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hbp_regs[hw_idx].address;
+ uint32_t tempControl = m_hbp_regs[hw_idx].control;
+
+ m_hbp_regs[hw_idx].control &= ~g_enable_bit;
+ m_hbp_regs[hw_idx].address = 0;
+
+ // PTRACE call to clear corresponding hardware breakpoint register.
+ error = WriteHardwareDebugRegs(eDREGTypeBREAK);
+
+ if (error) {
+ m_hbp_regs[hw_idx].control = tempControl;
+ m_hbp_regs[hw_idx].address = tempAddr;
+
+ LLDB_LOG_ERROR(
+ log, std::move(error),
+ "unable to clear breakpoint: failed to write debug registers: {0}");
+ return false;
+ }
+
+ return true;
+}
+
+Status NativeRegisterContextDBReg_arm64::GetHardwareBreakHitIndex(
+ uint32_t &bp_index, lldb::addr_t trap_addr) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+
+ LLDB_LOGF(log, "NativeRegisterContextDBReg_arm64::%s()", __FUNCTION__);
+
+ lldb::addr_t break_addr;
+
+ for (bp_index = 0; bp_index < m_max_hbp_supported; ++bp_index) {
+ break_addr = m_hbp_regs[bp_index].address;
+
+ if (BreakpointIsEnabled(bp_index) && trap_addr == break_addr) {
+ m_hbp_regs[bp_index].hit_addr = trap_addr;
+ return Status();
+ }
+ }
+
+ bp_index = LLDB_INVALID_INDEX32;
+ return Status();
+}
+
+Status NativeRegisterContextDBReg_arm64::ClearAllHardwareBreakpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+
+ LLDB_LOGF(log, "NativeRegisterContextDBReg_arm64::%s()", __FUNCTION__);
+
+ // Read hardware breakpoint and watchpoint information.
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error)
+ return Status(std::move(error));
+
+ for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
+ if (BreakpointIsEnabled(i)) {
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hbp_regs[i].address;
+ uint32_t tempControl = m_hbp_regs[i].control;
+
+ // Clear watchpoints in local cache
+ m_hbp_regs[i].control &= ~g_enable_bit;
+ m_hbp_regs[i].address = 0;
+
+ // Ptrace call to update hardware debug registers
+ error = WriteHardwareDebugRegs(eDREGTypeBREAK);
+
+ if (error) {
+ m_hbp_regs[i].control = tempControl;
+ m_hbp_regs[i].address = tempAddr;
+
+ return Status(std::move(error));
+ }
+ }
+ }
+
+ return Status();
+}
+
+bool NativeRegisterContextDBReg_arm64::BreakpointIsEnabled(uint32_t bp_index) {
+ if ((m_hbp_regs[bp_index].control & g_enable_bit) != 0)
+ return true;
+ else
+ return false;
+}
+
+uint32_t NativeRegisterContextDBReg_arm64::NumSupportedHardwareWatchpoints() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error) {
+ LLDB_LOG_ERROR(log, std::move(error),
+ "failed to read debug registers: {0}");
+ return 0;
+ }
+
+ return m_max_hwp_supported;
+}
+
+uint32_t NativeRegisterContextDBReg_arm64::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "addr: {0:x}, size: {1:x} watch_flags: {2:x}", addr, size,
+ watch_flags);
+
+ // Read hardware breakpoint and watchpoint information.
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error) {
+ LLDB_LOG_ERROR(
+ log, std::move(error),
+ "unable to set watchpoint: failed to read debug registers: {0}");
+ 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.
+ switch (watch_flags) {
+ case 1:
+ watch_flags = 2;
+ break;
+ case 2:
+ watch_flags = 1;
+ break;
+ case 3:
+ break;
+ default:
+ return LLDB_INVALID_INDEX32;
+ }
+
+ // Check if size has a valid hardware watchpoint length.
+ if (size != 1 && size != 2 && size != 4 && size != 8)
+ return LLDB_INVALID_INDEX32;
+
+ // Check 8-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 8-byte aligned addresses as well.
+ if (addr & 0x07) {
+ 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 = g_enable_bit | g_pac_bits | GetSizeBits(size);
+ control_value |= watch_flags << 3;
+
+ // Iterate over stored watchpoints and find a free wp_index
+ wp_index = LLDB_INVALID_INDEX32;
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ if (!WatchpointIsEnabled(i))
+ wp_index = i; // Mark last free slot
+ else if (m_hwp_regs[i].address == addr) {
+ return LLDB_INVALID_INDEX32; // We do not support duplicate watchpoints.
+ }
+ }
+
+ if (wp_index == LLDB_INVALID_INDEX32)
+ return LLDB_INVALID_INDEX32;
+
+ // 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;
+
+ // PTRACE call to set corresponding watchpoint register.
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH);
+
+ if (error) {
+ m_hwp_regs[wp_index].address = 0;
+ m_hwp_regs[wp_index].control &= ~g_enable_bit;
+
+ LLDB_LOG_ERROR(
+ log, std::move(error),
+ "unable to set watchpoint: failed to write debug registers: {0}");
+ return LLDB_INVALID_INDEX32;
+ }
+
+ return wp_index;
+}
+
+bool NativeRegisterContextDBReg_arm64::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ // Read hardware breakpoint and watchpoint information.
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error) {
+ LLDB_LOG_ERROR(
+ log, std::move(error),
+ "unable to clear watchpoint: failed to read debug registers: {0}");
+ return false;
+ }
+
+ if (wp_index >= m_max_hwp_supported)
+ return false;
+
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
+ uint32_t tempControl = m_hwp_regs[wp_index].control;
+
+ // Update watchpoint in local cache
+ m_hwp_regs[wp_index].control &= ~g_enable_bit;
+ m_hwp_regs[wp_index].address = 0;
+
+ // Ptrace call to update hardware debug registers
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH);
+
+ if (error) {
+ m_hwp_regs[wp_index].control = tempControl;
+ m_hwp_regs[wp_index].address = tempAddr;
+
+ LLDB_LOG_ERROR(
+ log, std::move(error),
+ "unable to clear watchpoint: failed to write debug registers: {0}");
+ return false;
+ }
+
+ return true;
+}
+
+Status NativeRegisterContextDBReg_arm64::ClearAllHardwareWatchpoints() {
+ // Read hardware breakpoint and watchpoint information.
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error)
+ return Status(std::move(error));
+
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ if (WatchpointIsEnabled(i)) {
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hwp_regs[i].address;
+ uint32_t tempControl = m_hwp_regs[i].control;
+
+ // Clear watchpoints in local cache
+ m_hwp_regs[i].control &= ~g_enable_bit;
+ m_hwp_regs[i].address = 0;
+
+ // Ptrace call to update hardware debug registers
+ error = WriteHardwareDebugRegs(eDREGTypeWATCH);
+
+ if (error) {
+ m_hwp_regs[i].control = tempControl;
+ m_hwp_regs[i].address = tempAddr;
+
+ return Status(std::move(error));
+ }
+ }
+ }
+
+ return Status();
+}
+
+uint32_t
+NativeRegisterContextDBReg_arm64::GetWatchpointSize(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ switch ((m_hwp_regs[wp_index].control >> 5) & 0xff) {
+ case 0x01:
+ return 1;
+ case 0x03:
+ return 2;
+ case 0x0f:
+ return 4;
+ case 0xff:
+ return 8;
+ default:
+ return 0;
+ }
+}
+
+bool NativeRegisterContextDBReg_arm64::WatchpointIsEnabled(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ if ((m_hwp_regs[wp_index].control & g_enable_bit) != 0)
+ return true;
+ else
+ return false;
+}
+
+Status NativeRegisterContextDBReg_arm64::GetWatchpointHitIndex(
+ uint32_t &wp_index, lldb::addr_t trap_addr) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}, trap_addr: {1:x}", wp_index, trap_addr);
+
+ // Read hardware breakpoint and watchpoint information.
+ llvm::Error error = ReadHardwareDebugInfo();
+ if (error)
+ return Status(std::move(error));
+
+ uint32_t watch_size;
+ lldb::addr_t watch_addr;
+
+ for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) {
+ watch_size = GetWatchpointSize(wp_index);
+ watch_addr = m_hwp_regs[wp_index].address;
+
+ if (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr &&
+ trap_addr < watch_addr + watch_size) {
+ m_hwp_regs[wp_index].hit_addr = trap_addr;
+ return Status();
+ }
+ }
+
+ wp_index = LLDB_INVALID_INDEX32;
+ return Status();
+}
+
+lldb::addr_t
+NativeRegisterContextDBReg_arm64::GetWatchpointAddress(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
+
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].real_addr;
+ return LLDB_INVALID_ADDRESS;
+}
+
+lldb::addr_t
+NativeRegisterContextDBReg_arm64::GetWatchpointHitAddress(uint32_t wp_index) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
+
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].hit_addr;
+ return LLDB_INVALID_ADDRESS;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h
new file mode 100644
index 000000000000..12ef5571f64c
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h
@@ -0,0 +1,79 @@
+//===-- NativeRegisterContextDBReg_arm64.h ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_NativeRegisterContextDBReg_arm64_h
+#define lldb_NativeRegisterContextDBReg_arm64_h
+
+#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
+
+#include <array>
+
+namespace lldb_private {
+
+class NativeRegisterContextDBReg_arm64
+ : public virtual NativeRegisterContextRegisterInfo {
+public:
+ uint32_t NumSupportedHardwareBreakpoints() override;
+
+ uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
+
+ bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
+
+ Status ClearAllHardwareBreakpoints() override;
+
+ Status GetHardwareBreakHitIndex(uint32_t &bp_index,
+ lldb::addr_t trap_addr) override;
+
+ bool BreakpointIsEnabled(uint32_t bp_index);
+
+ uint32_t NumSupportedHardwareWatchpoints() override;
+
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
+
+ bool ClearHardwareWatchpoint(uint32_t hw_index) override;
+
+ Status ClearAllHardwareWatchpoints() override;
+
+ Status 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 GetWatchpointSize(uint32_t wp_index);
+
+ bool WatchpointIsEnabled(uint32_t wp_index);
+
+ // Debug register type select
+ enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK };
+
+protected:
+ // Debug register info for hardware breakpoints and watchpoints management.
+ 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.
+ };
+
+ std::array<struct DREG, 16> m_hbp_regs; // hardware breakpoints
+ std::array<struct DREG, 16> m_hwp_regs; // hardware watchpoints
+
+ uint32_t m_max_hbp_supported;
+ uint32_t m_max_hwp_supported;
+
+ virtual llvm::Error ReadHardwareDebugInfo() = 0;
+ virtual llvm::Error WriteHardwareDebugRegs(DREGType hwbType) = 0;
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextDBReg_arm64_h
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp
new file mode 100644
index 000000000000..56c1757ee89d
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp
@@ -0,0 +1,276 @@
+//===-- NativeRegisterContextDBReg_x86.cpp --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeRegisterContextDBReg_x86.h"
+
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+
+#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
+
+using namespace lldb_private;
+
+// Returns mask/value for status bit of wp_index in DR6
+static inline uint64_t GetStatusBit(uint32_t wp_index) {
+ // DR6: ...BBBB
+ // 3210 <- status bits for bp./wp. i; 1 if hit
+ return 1 << wp_index;
+}
+
+// Returns mask/value for global enable bit of wp_index in DR7
+static inline uint64_t GetEnableBit(uint32_t wp_index) {
+ // DR7: ...GLGLGLGL
+ // 33221100 <- global/local enable for bp./wp.; 1 if enabled
+ // we use global bits because NetBSD kernel does not preserve local
+ // bits reliably; Linux seems fine with either
+ return 1 << (2 * wp_index + 1);
+}
+
+// Returns mask for both enable bits of wp_index in DR7
+static inline uint64_t GetBothEnableBitMask(uint32_t wp_index) {
+ // DR7: ...GLGLGLGL
+ // 33221100 <- global/local enable for bp./wp.; 1 if enabled
+ return 3 << (2 * wp_index + 1);
+}
+
+// Returns value for type bits of wp_index in DR7
+static inline uint64_t GetWatchTypeBits(uint32_t watch_flags,
+ uint32_t wp_index) {
+ // DR7:
+ // bit: 3322222222221111...
+ // 1098765432109876...
+ // val: SSTTSSTTSSTTSSTT...
+ // wp.: 3333222211110000...
+ //
+ // where T - type is 01 for write, 11 for r/w
+ return watch_flags << (16 + 4 * wp_index);
+}
+
+// Returns value for size bits of wp_index in DR7
+static inline uint64_t GetWatchSizeBits(uint32_t size, uint32_t wp_index) {
+ // DR7:
+ // bit: 3322222222221111...
+ // 1098765432109876...
+ // val: SSTTSSTTSSTTSSTT...
+ // wp.: 3333222211110000...
+ //
+ // where S - size is:
+ // 00 for 1 byte
+ // 01 for 2 bytes
+ // 10 for 8 bytes
+ // 11 for 4 bytes
+ return (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index);
+}
+
+// Returns bitmask for all bits controlling wp_index in DR7
+static inline uint64_t GetWatchControlBitmask(uint32_t wp_index) {
+ // DR7:
+ // bit: 33222222222211111111110000000000
+ // 10987654321098765432109876543210
+ // val: SSTTSSTTSSTTSSTTxxxxxxGLGLGLGLGL
+ // wp.: 3333222211110000xxxxxxEE33221100
+ return GetBothEnableBitMask(wp_index) | (0xF << (16 + 4 * wp_index));
+}
+
+// Bit mask for control bits regarding all watchpoints.
+static constexpr uint64_t watchpoint_all_control_bit_mask = 0xFFFF00FF;
+
+const RegisterInfo *NativeRegisterContextDBReg_x86::GetDR(int num) const {
+ assert(num >= 0 && num <= 7);
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::x86:
+ return GetRegisterInfoAtIndex(lldb_dr0_i386 + num);
+ case llvm::Triple::x86_64:
+ return GetRegisterInfoAtIndex(lldb_dr0_x86_64 + num);
+ default:
+ llvm_unreachable("Unhandled target architecture.");
+ }
+}
+
+Status NativeRegisterContextDBReg_x86::IsWatchpointHit(uint32_t wp_index,
+ bool &is_hit) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Status("Watchpoint index out of range");
+
+ RegisterValue dr6;
+ Status error = ReadRegister(GetDR(6), dr6);
+ if (error.Fail())
+ is_hit = false;
+ else
+ is_hit = dr6.GetAsUInt64() & GetStatusBit(wp_index);
+
+ return error;
+}
+
+Status
+NativeRegisterContextDBReg_x86::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;
+ Status 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 Status();
+}
+
+Status NativeRegisterContextDBReg_x86::IsWatchpointVacant(uint32_t wp_index,
+ bool &is_vacant) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Status("Watchpoint index out of range");
+
+ RegisterValue dr7;
+ Status error = ReadRegister(GetDR(7), dr7);
+ if (error.Fail())
+ is_vacant = false;
+ else
+ is_vacant = !(dr7.GetAsUInt64() & GetEnableBit(wp_index));
+
+ return error;
+}
+
+Status NativeRegisterContextDBReg_x86::SetHardwareWatchpointWithIndex(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
+
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Status("Watchpoint index out of range");
+
+ // Read only watchpoints aren't supported on x86_64. Fall back to read/write
+ // waitchpoints instead.
+ // TODO: Add logic to detect when a write happens and ignore that watchpoint
+ // hit.
+ if (watch_flags == 2)
+ watch_flags = 3;
+
+ if (watch_flags != 1 && watch_flags != 3)
+ return Status("Invalid read/write bits for watchpoint");
+ if (size != 1 && size != 2 && size != 4 && size != 8)
+ return Status("Invalid size for watchpoint");
+
+ bool is_vacant;
+ Status error = IsWatchpointVacant(wp_index, is_vacant);
+ if (error.Fail())
+ return error;
+ if (!is_vacant)
+ return Status("Watchpoint index not vacant");
+
+ RegisterValue dr7, drN;
+ error = ReadRegister(GetDR(7), dr7);
+ if (error.Fail())
+ return error;
+ error = ReadRegister(GetDR(wp_index), drN);
+ if (error.Fail())
+ return error;
+
+ uint64_t control_bits = dr7.GetAsUInt64() & ~GetWatchControlBitmask(wp_index);
+ control_bits |= GetEnableBit(wp_index) |
+ GetWatchTypeBits(watch_flags, wp_index) |
+ GetWatchSizeBits(size, wp_index);
+
+ // Clear dr6 if address or bits changed (i.e. we're not reenabling the same
+ // watchpoint). This can not be done when clearing watchpoints since
+ // the gdb-remote protocol repeatedly clears and readds watchpoints on all
+ // program threads, effectively clearing pending events on NetBSD.
+ // NB: enable bits in dr7 are always 0 here since we're (re)adding it
+ if (drN.GetAsUInt64() != addr ||
+ (dr7.GetAsUInt64() & GetWatchControlBitmask(wp_index)) !=
+ (GetWatchTypeBits(watch_flags, wp_index) |
+ GetWatchSizeBits(size, wp_index))) {
+ ClearWatchpointHit(wp_index);
+
+ // We skip update to drN if neither address nor mode changed.
+ error = WriteRegister(GetDR(wp_index), RegisterValue(addr));
+ if (error.Fail())
+ return error;
+ }
+
+ error = WriteRegister(GetDR(7), RegisterValue(control_bits));
+ if (error.Fail())
+ return error;
+
+ return error;
+}
+
+bool NativeRegisterContextDBReg_x86::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return false;
+
+ RegisterValue dr7;
+ Status error = ReadRegister(GetDR(7), dr7);
+ if (error.Fail())
+ return false;
+
+ return WriteRegister(GetDR(7), RegisterValue(dr7.GetAsUInt64() &
+ ~GetBothEnableBitMask(wp_index)))
+ .Success();
+}
+
+Status NativeRegisterContextDBReg_x86::ClearWatchpointHit(uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return Status("Watchpoint index out of range");
+
+ RegisterValue dr6;
+ Status error = ReadRegister(GetDR(6), dr6);
+ if (error.Fail())
+ return error;
+
+ return WriteRegister(
+ GetDR(6), RegisterValue(dr6.GetAsUInt64() & ~GetStatusBit(wp_index)));
+}
+
+Status NativeRegisterContextDBReg_x86::ClearAllHardwareWatchpoints() {
+ RegisterValue dr7;
+ Status error = ReadRegister(GetDR(7), dr7);
+ if (error.Fail())
+ return error;
+ return WriteRegister(
+ GetDR(7),
+ RegisterValue(dr7.GetAsUInt64() & ~watchpoint_all_control_bit_mask));
+}
+
+uint32_t NativeRegisterContextDBReg_x86::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) {
+ bool is_vacant;
+ Status error = IsWatchpointVacant(wp_index, is_vacant);
+ if (is_vacant) {
+ error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
+ if (error.Success())
+ return wp_index;
+ }
+ if (error.Fail() && log) {
+ LLDB_LOGF(log, "NativeRegisterContextDBReg_x86::%s Error: %s",
+ __FUNCTION__, error.AsCString());
+ }
+ }
+ return LLDB_INVALID_INDEX32;
+}
+
+lldb::addr_t
+NativeRegisterContextDBReg_x86::GetWatchpointAddress(uint32_t wp_index) {
+ if (wp_index >= NumSupportedHardwareWatchpoints())
+ return LLDB_INVALID_ADDRESS;
+ RegisterValue drN;
+ if (ReadRegister(GetDR(wp_index), drN).Fail())
+ return LLDB_INVALID_ADDRESS;
+ return drN.GetAsUInt64();
+}
+
+uint32_t NativeRegisterContextDBReg_x86::NumSupportedHardwareWatchpoints() {
+ // Available debug address registers: dr0, dr1, dr2, dr3
+ return 4;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h
new file mode 100644
index 000000000000..c0c6ce29eab5
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h
@@ -0,0 +1,48 @@
+//===-- NativeRegisterContextDBReg_x86.h ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_NativeRegisterContextDBReg_x86_h
+#define lldb_NativeRegisterContextDBReg_x86_h
+
+#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
+
+namespace lldb_private {
+
+class NativeRegisterContextDBReg_x86
+ : public virtual NativeRegisterContextRegisterInfo {
+public:
+ Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
+
+ Status GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
+
+ Status IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
+
+ bool ClearHardwareWatchpoint(uint32_t wp_index) override;
+
+ Status ClearWatchpointHit(uint32_t wp_index) override;
+
+ Status ClearAllHardwareWatchpoints() override;
+
+ Status SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags,
+ uint32_t wp_index);
+
+ 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;
+
+ const RegisterInfo *GetDR(int num) const;
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextDBReg_x86_h
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
index 10d346a3cb7e..acebe9d53568 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp
@@ -35,7 +35,7 @@ struct GPR {
uint32_t gs;
};
-struct dbreg {
+struct DBG {
uint32_t dr[8]; /* debug registers */
/* Index 0-3: debug address registers */
/* Index 4-5: reserved */
@@ -48,10 +48,13 @@ using FPR_i386 = FXSAVE;
struct UserArea {
GPR gpr;
FPR_i386 i387;
+ DBG dbg;
};
#define DR_SIZE sizeof(uint32_t)
-#define DR_OFFSET(reg_index) (LLVM_EXTENSION offsetof(dbreg, dr[reg_index]))
+#define DR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, dbg) + \
+ LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure.
#define DECLARE_REGISTER_INFOS_I386_STRUCT
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
index c1f390ade9b9..e0f3971c6e27 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp
@@ -59,7 +59,9 @@ struct UserArea {
DBG dbg;
};
-#define DR_OFFSET(reg_index) (LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
+#define DR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, dbg) + \
+ LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64
// structure.
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h
index e7c180dbdd27..1ceca65c97c3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h
@@ -19,21 +19,21 @@ public:
virtual ~RegisterContextMach_arm();
protected:
- virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+ int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override;
- int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override;
- int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override;
- int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg);
+ int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) override;
- int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override;
- int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override;
- int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override;
- int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg);
+ int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg) override;
};
#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_ARM_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h
index 09966be60c92..da5411eb2de2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h
@@ -19,17 +19,17 @@ public:
virtual ~RegisterContextMach_i386();
protected:
- virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+ int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override;
- int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override;
- int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override;
- int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override;
- int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override;
- int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override;
};
#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_I386_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
index 2a8a2cca2f8a..c131c8282bd2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
@@ -20,17 +20,17 @@ public:
virtual ~RegisterContextMach_x86_64();
protected:
- virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
+ int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override;
- int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
+ int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override;
- int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
+ int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override;
- int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
+ int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override;
- int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
+ int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override;
- int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
+ int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override;
};
#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTMACH_X86_64_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
index 617893b6b3b0..97a760396ba9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
@@ -25,88 +25,25 @@
using namespace lldb;
using namespace lldb_private;
-// arm general purpose registers.
-const uint32_t g_gpr_regnums_arm[] = {
- gpr_r0_arm, gpr_r1_arm, gpr_r2_arm, gpr_r3_arm, gpr_r4_arm,
- gpr_r5_arm, gpr_r6_arm, gpr_r7_arm, gpr_r8_arm, gpr_r9_arm,
- gpr_r10_arm, gpr_r11_arm, gpr_r12_arm, gpr_sp_arm, gpr_lr_arm,
- gpr_pc_arm, gpr_cpsr_arm,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-
-};
-static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) ==
- k_num_gpr_registers_arm,
- "g_gpr_regnums_arm has wrong number of register infos");
-
-// arm floating point registers.
-static const uint32_t g_fpu_regnums_arm[] = {
- fpu_s0_arm, fpu_s1_arm, fpu_s2_arm, fpu_s3_arm, fpu_s4_arm,
- fpu_s5_arm, fpu_s6_arm, fpu_s7_arm, fpu_s8_arm, fpu_s9_arm,
- fpu_s10_arm, fpu_s11_arm, fpu_s12_arm, fpu_s13_arm, fpu_s14_arm,
- fpu_s15_arm, fpu_s16_arm, fpu_s17_arm, fpu_s18_arm, fpu_s19_arm,
- fpu_s20_arm, fpu_s21_arm, fpu_s22_arm, fpu_s23_arm, fpu_s24_arm,
- fpu_s25_arm, fpu_s26_arm, fpu_s27_arm, fpu_s28_arm, fpu_s29_arm,
- fpu_s30_arm, fpu_s31_arm, fpu_fpscr_arm, fpu_d0_arm, fpu_d1_arm,
- fpu_d2_arm, fpu_d3_arm, fpu_d4_arm, fpu_d5_arm, fpu_d6_arm,
- fpu_d7_arm, fpu_d8_arm, fpu_d9_arm, fpu_d10_arm, fpu_d11_arm,
- fpu_d12_arm, fpu_d13_arm, fpu_d14_arm, fpu_d15_arm, fpu_d16_arm,
- fpu_d17_arm, fpu_d18_arm, fpu_d19_arm, fpu_d20_arm, fpu_d21_arm,
- fpu_d22_arm, fpu_d23_arm, fpu_d24_arm, fpu_d25_arm, fpu_d26_arm,
- fpu_d27_arm, fpu_d28_arm, fpu_d29_arm, fpu_d30_arm, fpu_d31_arm,
- fpu_q0_arm, fpu_q1_arm, fpu_q2_arm, fpu_q3_arm, fpu_q4_arm,
- fpu_q5_arm, fpu_q6_arm, fpu_q7_arm, fpu_q8_arm, fpu_q9_arm,
- fpu_q10_arm, fpu_q11_arm, fpu_q12_arm, fpu_q13_arm, fpu_q14_arm,
- fpu_q15_arm,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-
-};
-static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) ==
- k_num_fpr_registers_arm,
- "g_fpu_regnums_arm has wrong number of register infos");
-
-// Number of register sets provided by this context.
-enum { k_num_register_sets = 2 };
-
-// Register sets for arm.
-static const lldb_private::RegisterSet g_reg_sets_arm[k_num_register_sets] = {
- {"General Purpose Registers", "gpr", k_num_gpr_registers_arm,
- g_gpr_regnums_arm},
- {"Floating Point Registers", "fpu", k_num_fpr_registers_arm,
- g_fpu_regnums_arm}};
-
bool RegisterContextPOSIX_arm::IsGPR(unsigned reg) {
- return reg <= m_reg_info.last_gpr; // GPR's come first.
+ if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) ==
+ RegisterInfoPOSIX_arm::GPRegSet)
+ return true;
+ return false;
}
bool RegisterContextPOSIX_arm::IsFPR(unsigned reg) {
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+ if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) ==
+ RegisterInfoPOSIX_arm::FPRegSet)
+ return true;
+ return false;
}
RegisterContextPOSIX_arm::RegisterContextPOSIX_arm(
- lldb_private::Thread &thread, uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info)
- : lldb_private::RegisterContext(thread, concrete_frame_idx) {
- m_register_info_up.reset(register_info);
-
- switch (register_info->m_target_arch.GetMachine()) {
- case llvm::Triple::arm:
- m_reg_info.num_registers = k_num_registers_arm;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
- m_reg_info.last_gpr = k_last_gpr_arm;
- m_reg_info.first_fpr = k_first_fpr_arm;
- m_reg_info.last_fpr = k_last_fpr_arm;
- m_reg_info.first_fpr_v = fpu_s0_arm;
- m_reg_info.last_fpr_v = fpu_s31_arm;
- m_reg_info.gpr_flags = gpr_cpsr_arm;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
-
- ::memset(&m_fpr, 0, sizeof m_fpr);
-}
+ lldb_private::Thread &thread,
+ std::unique_ptr<RegisterInfoPOSIX_arm> register_info)
+ : lldb_private::RegisterContext(thread, 0),
+ m_register_info_up(std::move(register_info)) {}
RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm() {}
@@ -115,19 +52,15 @@ void RegisterContextPOSIX_arm::Invalidate() {}
void RegisterContextPOSIX_arm::InvalidateAllRegisters() {}
unsigned RegisterContextPOSIX_arm::GetRegisterOffset(unsigned reg) {
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_offset;
+ return m_register_info_up->GetRegisterInfo()[reg].byte_offset;
}
unsigned RegisterContextPOSIX_arm::GetRegisterSize(unsigned reg) {
- assert(reg < m_reg_info.num_registers && "Invalid register number.");
- return GetRegisterInfo()[reg].byte_size;
+ return m_register_info_up->GetRegisterInfo()[reg].byte_size;
}
size_t RegisterContextPOSIX_arm::GetRegisterCount() {
- size_t num_registers =
- m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
- return num_registers;
+ return m_register_info_up->GetRegisterCount();
}
size_t RegisterContextPOSIX_arm::GetGPRSize() {
@@ -143,41 +76,23 @@ const lldb_private::RegisterInfo *RegisterContextPOSIX_arm::GetRegisterInfo() {
const lldb_private::RegisterInfo *
RegisterContextPOSIX_arm::GetRegisterInfoAtIndex(size_t reg) {
- if (reg < m_reg_info.num_registers)
+ if (reg < GetRegisterCount())
return &GetRegisterInfo()[reg];
- else
- return nullptr;
+
+ return nullptr;
}
size_t RegisterContextPOSIX_arm::GetRegisterSetCount() {
- size_t sets = 0;
- for (size_t set = 0; set < k_num_register_sets; ++set) {
- if (IsRegisterSetAvailable(set))
- ++sets;
- }
-
- return sets;
+ return m_register_info_up->GetRegisterSetCount();
}
const lldb_private::RegisterSet *
RegisterContextPOSIX_arm::GetRegisterSet(size_t set) {
- if (IsRegisterSetAvailable(set)) {
- switch (m_register_info_up->m_target_arch.GetMachine()) {
- case llvm::Triple::arm:
- return &g_reg_sets_arm[set];
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
- }
- return nullptr;
+ return m_register_info_up->GetRegisterSet(set);
}
const char *RegisterContextPOSIX_arm::GetRegisterName(unsigned reg) {
- assert(reg < m_reg_info.num_registers && "Invalid register offset.");
- return GetRegisterInfo()[reg].name;
-}
-
-bool RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index) {
- return set_index < k_num_register_sets;
+ if (reg < GetRegisterCount())
+ return GetRegisterInfo()[reg].name;
+ return nullptr;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
index d6967f05ed48..099c37d46f49 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
@@ -10,17 +10,15 @@
#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_ARM_H
#include "RegisterInfoInterface.h"
-#include "lldb-arm-register-enums.h"
+#include "RegisterInfoPOSIX_arm.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Log.h"
-class ProcessMonitor;
-
class RegisterContextPOSIX_arm : public lldb_private::RegisterContext {
public:
- RegisterContextPOSIX_arm(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx,
- lldb_private::RegisterInfoInterface *register_info);
+ RegisterContextPOSIX_arm(
+ lldb_private::Thread &thread,
+ std::unique_ptr<RegisterInfoPOSIX_arm> register_info);
~RegisterContextPOSIX_arm() override;
@@ -45,46 +43,7 @@ public:
const char *GetRegisterName(unsigned reg);
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;
-
- uint32_t first_fpr_v;
- uint32_t last_fpr_v;
-
- uint32_t gpr_flags;
- };
-
- struct QReg {
- uint8_t bytes[16];
- };
-
- struct FPU {
- union {
- uint32_t s[32];
- uint64_t d[32];
- QReg q[16]; // the 128-bit NEON registers
- } floats;
- uint32_t fpscr;
- };
-
- uint32_t m_gpr_arm[lldb_private::k_num_gpr_registers_arm]; // 32-bit general
- // purpose
- // registers.
- RegInfo m_reg_info;
- struct RegisterContextPOSIX_arm::FPU
- m_fpr; // floating-point registers including extended register sets.
- std::unique_ptr<lldb_private::RegisterInfoInterface>
- m_register_info_up; // Register Info Interface (FreeBSD or Linux)
-
- // Determines if an extended register set is supported on the processor
- // running the inferior process.
- virtual bool IsRegisterSetAvailable(size_t set_index);
+ std::unique_ptr<RegisterInfoPOSIX_arm> m_register_info_up;
virtual const lldb_private::RegisterInfo *GetRegisterInfo();
@@ -92,6 +51,8 @@ protected:
bool IsFPR(unsigned reg);
+ size_t GetFPUSize() { return sizeof(RegisterInfoPOSIX_arm::FPU); }
+
virtual bool ReadGPR() = 0;
virtual bool ReadFPR() = 0;
virtual bool WriteGPR() = 0;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
index 8ef587f13e3a..3f52501c35f3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
@@ -39,14 +39,18 @@ bool RegisterContextPOSIX_arm64::IsFPR(unsigned reg) {
return false;
}
+bool RegisterContextPOSIX_arm64::IsSVE(unsigned reg) const {
+ if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) ==
+ RegisterInfoPOSIX_arm64::SVERegSet)
+ return true;
+ return false;
+}
+
RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
lldb_private::Thread &thread,
std::unique_ptr<RegisterInfoPOSIX_arm64> register_info)
: lldb_private::RegisterContext(thread, 0),
- m_register_info_up(std::move(register_info)) {
-
- ::memset(&m_fpr, 0, sizeof m_fpr);
-}
+ m_register_info_up(std::move(register_info)) {}
RegisterContextPOSIX_arm64::~RegisterContextPOSIX_arm64() {}
@@ -82,8 +86,8 @@ const lldb_private::RegisterInfo *
RegisterContextPOSIX_arm64::GetRegisterInfoAtIndex(size_t reg) {
if (reg < GetRegisterCount())
return &GetRegisterInfo()[reg];
- else
- return nullptr;
+
+ return nullptr;
}
size_t RegisterContextPOSIX_arm64::GetRegisterSetCount() {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
index c2d5aee7f73c..a3f07bb2823b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
@@ -11,12 +11,9 @@
#include "RegisterInfoInterface.h"
#include "RegisterInfoPOSIX_arm64.h"
-#include "lldb-arm64-register-enums.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Log.h"
-class ProcessMonitor;
-
class RegisterContextPOSIX_arm64 : public lldb_private::RegisterContext {
public:
RegisterContextPOSIX_arm64(
@@ -46,13 +43,6 @@ public:
const char *GetRegisterName(unsigned reg);
protected:
- uint64_t m_gpr_arm64[lldb_private::k_num_gpr_registers_arm64]; // 64-bit
- // general
- // purpose
- // registers.
-
- struct RegisterInfoPOSIX_arm64::FPU
- m_fpr; // floating-point registers including extended register sets.
std::unique_ptr<RegisterInfoPOSIX_arm64> m_register_info_up;
virtual const lldb_private::RegisterInfo *GetRegisterInfo();
@@ -63,6 +53,23 @@ protected:
size_t GetFPUSize() { return sizeof(RegisterInfoPOSIX_arm64::FPU); }
+ bool IsSVE(unsigned reg) const;
+
+ bool IsSVEZ(unsigned reg) const { return m_register_info_up->IsSVEZReg(reg); }
+ bool IsSVEP(unsigned reg) const { return m_register_info_up->IsSVEPReg(reg); }
+ bool IsSVEVG(unsigned reg) const {
+ return m_register_info_up->IsSVERegVG(reg);
+ }
+
+ uint32_t GetRegNumSVEZ0() const {
+ return m_register_info_up->GetRegNumSVEZ0();
+ }
+ uint32_t GetRegNumSVEFFR() const {
+ return m_register_info_up->GetRegNumSVEFFR();
+ }
+ uint32_t GetRegNumFPCR() const { return m_register_info_up->GetRegNumFPCR(); }
+ uint32_t GetRegNumFPSR() const { return m_register_info_up->GetRegNumFPSR(); }
+
virtual bool ReadGPR() = 0;
virtual bool ReadFPR() = 0;
virtual bool WriteGPR() = 0;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
index 1843a2a6aff3..b66dc3f44524 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
@@ -14,10 +14,6 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Log.h"
-using namespace lldb_private;
-
-class ProcessMonitor;
-
class RegisterContextPOSIX_mips64 : public lldb_private::RegisterContext {
public:
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
index e2c33461c8f1..5dd8c890da6e 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
@@ -14,8 +14,6 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Log.h"
-class ProcessMonitor;
-
// Internal codes for all powerpc registers.
enum {
k_first_gpr_powerpc,
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
index 7df732d13ffa..7027af04f0bb 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
@@ -15,8 +15,6 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Log.h"
-class ProcessMonitor;
-
class RegisterContextPOSIX_s390x : public lldb_private::RegisterContext {
public:
RegisterContextPOSIX_s390x(
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
index ac271a90d6a1..2c7f63503d7c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
@@ -119,20 +119,21 @@ static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
"g_gpr_regnums_x86_64 has wrong number of register infos");
static const uint32_t g_lldb_regnums_x86_64[] = {
- lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64,
- lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64,
- lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_mxcsr_x86_64,
- lldb_mxcsrmask_x86_64, lldb_st0_x86_64, lldb_st1_x86_64,
- lldb_st2_x86_64, lldb_st3_x86_64, lldb_st4_x86_64,
- lldb_st5_x86_64, lldb_st6_x86_64, lldb_st7_x86_64,
- lldb_mm0_x86_64, lldb_mm1_x86_64, lldb_mm2_x86_64,
- lldb_mm3_x86_64, lldb_mm4_x86_64, lldb_mm5_x86_64,
- lldb_mm6_x86_64, lldb_mm7_x86_64, lldb_xmm0_x86_64,
- lldb_xmm1_x86_64, lldb_xmm2_x86_64, lldb_xmm3_x86_64,
- lldb_xmm4_x86_64, lldb_xmm5_x86_64, lldb_xmm6_x86_64,
- lldb_xmm7_x86_64, lldb_xmm8_x86_64, lldb_xmm9_x86_64,
- lldb_xmm10_x86_64, lldb_xmm11_x86_64, lldb_xmm12_x86_64,
- lldb_xmm13_x86_64, lldb_xmm14_x86_64, lldb_xmm15_x86_64,
+ lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64,
+ lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64,
+ lldb_fip_x86_64, lldb_foseg_x86_64, lldb_fooff_x86_64,
+ lldb_fdp_x86_64, lldb_mxcsr_x86_64, lldb_mxcsrmask_x86_64,
+ lldb_st0_x86_64, lldb_st1_x86_64, lldb_st2_x86_64,
+ lldb_st3_x86_64, lldb_st4_x86_64, lldb_st5_x86_64,
+ lldb_st6_x86_64, lldb_st7_x86_64, lldb_mm0_x86_64,
+ lldb_mm1_x86_64, lldb_mm2_x86_64, lldb_mm3_x86_64,
+ lldb_mm4_x86_64, lldb_mm5_x86_64, lldb_mm6_x86_64,
+ lldb_mm7_x86_64, lldb_xmm0_x86_64, lldb_xmm1_x86_64,
+ lldb_xmm2_x86_64, lldb_xmm3_x86_64, lldb_xmm4_x86_64,
+ lldb_xmm5_x86_64, lldb_xmm6_x86_64, lldb_xmm7_x86_64,
+ lldb_xmm8_x86_64, lldb_xmm9_x86_64, lldb_xmm10_x86_64,
+ lldb_xmm11_x86_64, lldb_xmm12_x86_64, lldb_xmm13_x86_64,
+ lldb_xmm14_x86_64, lldb_xmm15_x86_64,
LLDB_INVALID_REGNUM // Register sets must be terminated with
// LLDB_INVALID_REGNUM.
};
@@ -275,6 +276,84 @@ uint32_t RegisterContextPOSIX_x86::g_invalidate_r15[] = {
lldb_r15_x86_64, lldb_r15d_x86_64, lldb_r15w_x86_64, lldb_r15l_x86_64,
LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_fip[] = {lldb_fip_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_fdp[] = {lldb_fdp_x86_64,
+ LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_invalidate_fip[] = {
+ lldb_fip_x86_64, lldb_fioff_x86_64, lldb_fiseg_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_fdp[] = {
+ lldb_fdp_x86_64, lldb_fooff_x86_64, lldb_foseg_x86_64, LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_contained_st0_32[] = {lldb_st0_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st1_32[] = {lldb_st1_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st2_32[] = {lldb_st2_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st3_32[] = {lldb_st3_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st4_32[] = {lldb_st4_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st5_32[] = {lldb_st5_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st6_32[] = {lldb_st6_i386,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st7_32[] = {lldb_st7_i386,
+ LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st0_32[] = {
+ lldb_st0_i386, lldb_mm0_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st1_32[] = {
+ lldb_st1_i386, lldb_mm1_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st2_32[] = {
+ lldb_st2_i386, lldb_mm2_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st3_32[] = {
+ lldb_st3_i386, lldb_mm3_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st4_32[] = {
+ lldb_st4_i386, lldb_mm4_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st5_32[] = {
+ lldb_st5_i386, lldb_mm5_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st6_32[] = {
+ lldb_st6_i386, lldb_mm6_i386, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st7_32[] = {
+ lldb_st7_i386, lldb_mm7_i386, LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_contained_st0_64[] = {lldb_st0_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st1_64[] = {lldb_st1_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st2_64[] = {lldb_st2_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st3_64[] = {lldb_st3_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st4_64[] = {lldb_st4_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st5_64[] = {lldb_st5_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st6_64[] = {lldb_st6_x86_64,
+ LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_contained_st7_64[] = {lldb_st7_x86_64,
+ LLDB_INVALID_REGNUM};
+
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st0_64[] = {
+ lldb_st0_x86_64, lldb_mm0_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st1_64[] = {
+ lldb_st1_x86_64, lldb_mm1_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st2_64[] = {
+ lldb_st2_x86_64, lldb_mm2_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st3_64[] = {
+ lldb_st3_x86_64, lldb_mm3_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st4_64[] = {
+ lldb_st4_x86_64, lldb_mm4_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st5_64[] = {
+ lldb_st5_x86_64, lldb_mm5_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st6_64[] = {
+ lldb_st6_x86_64, lldb_mm6_x86_64, LLDB_INVALID_REGNUM};
+uint32_t RegisterContextPOSIX_x86::g_invalidate_st7_64[] = {
+ lldb_st7_x86_64, lldb_mm7_x86_64, LLDB_INVALID_REGNUM};
+
// Number of register sets provided by this context.
enum { k_num_extended_register_sets = 1, k_num_register_sets = 3 };
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
index c4886ae618a2..d6672835b4a8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
@@ -15,8 +15,6 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Log.h"
-class ProcessMonitor;
-
class RegisterContextPOSIX_x86 : public lldb_private::RegisterContext {
public:
RegisterContextPOSIX_x86(lldb_private::Thread &thread,
@@ -108,6 +106,48 @@ public:
static uint32_t g_invalidate_r14[];
static uint32_t g_invalidate_r15[];
+ static uint32_t g_contained_fip[];
+ static uint32_t g_contained_fdp[];
+
+ static uint32_t g_invalidate_fip[];
+ static uint32_t g_invalidate_fdp[];
+
+ static uint32_t g_contained_st0_32[];
+ static uint32_t g_contained_st1_32[];
+ static uint32_t g_contained_st2_32[];
+ static uint32_t g_contained_st3_32[];
+ static uint32_t g_contained_st4_32[];
+ static uint32_t g_contained_st5_32[];
+ static uint32_t g_contained_st6_32[];
+ static uint32_t g_contained_st7_32[];
+
+ static uint32_t g_invalidate_st0_32[];
+ static uint32_t g_invalidate_st1_32[];
+ static uint32_t g_invalidate_st2_32[];
+ static uint32_t g_invalidate_st3_32[];
+ static uint32_t g_invalidate_st4_32[];
+ static uint32_t g_invalidate_st5_32[];
+ static uint32_t g_invalidate_st6_32[];
+ static uint32_t g_invalidate_st7_32[];
+
+ static uint32_t g_contained_st0_64[];
+ static uint32_t g_contained_st1_64[];
+ static uint32_t g_contained_st2_64[];
+ static uint32_t g_contained_st3_64[];
+ static uint32_t g_contained_st4_64[];
+ static uint32_t g_contained_st5_64[];
+ static uint32_t g_contained_st6_64[];
+ static uint32_t g_contained_st7_64[];
+
+ static uint32_t g_invalidate_st0_64[];
+ static uint32_t g_invalidate_st1_64[];
+ static uint32_t g_invalidate_st2_64[];
+ static uint32_t g_invalidate_st3_64[];
+ static uint32_t g_invalidate_st4_64[];
+ static uint32_t g_invalidate_st5_64[];
+ static uint32_t g_invalidate_st6_64[];
+ static uint32_t g_invalidate_st7_64[];
+
protected:
struct RegInfo {
uint32_t num_registers;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.cpp
new file mode 100644
index 000000000000..b21c72bd9621
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.cpp
@@ -0,0 +1,58 @@
+//===-- RegisterContext_x86.cpp ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContext_x86.h"
+
+using namespace lldb_private;
+
+// Convert the 8-bit abridged FPU Tag Word (as found in FXSAVE) to the full
+// 16-bit FPU Tag Word (as found in FSAVE, and used by gdb protocol). This
+// requires knowing the values of the ST(i) registers and the FPU Status Word.
+uint16_t lldb_private::AbridgedToFullTagWord(uint8_t abridged_tw, uint16_t sw,
+ llvm::ArrayRef<MMSReg> st_regs) {
+ // Tag word is using internal FPU register numbering rather than ST(i).
+ // Mapping to ST(i): i = FPU regno - TOP (Status Word, bits 11:13).
+ // Here we start with FPU reg 7 and go down.
+ int st = 7 - ((sw >> 11) & 7);
+ uint16_t tw = 0;
+ for (uint8_t mask = 0x80; mask != 0; mask >>= 1) {
+ tw <<= 2;
+ if (abridged_tw & mask) {
+ // The register is non-empty, so we need to check the value of ST(i).
+ uint16_t exp =
+ st_regs[st].comp.sign_exp & 0x7fff; // Discard the sign bit.
+ if (exp == 0) {
+ if (st_regs[st].comp.mantissa == 0)
+ tw |= 1; // Zero
+ else
+ tw |= 2; // Denormal
+ } else if (exp == 0x7fff)
+ tw |= 2; // Infinity or NaN
+ // 0 if normal number
+ } else
+ tw |= 3; // Empty register
+
+ // Rotate ST down.
+ st = (st - 1) & 7;
+ }
+
+ return tw;
+}
+
+// Convert the 16-bit FPU Tag Word to the abridged 8-bit value, to be written
+// into FXSAVE.
+uint8_t lldb_private::FullToAbridgedTagWord(uint16_t tw) {
+ uint8_t abridged_tw = 0;
+ for (uint16_t mask = 0xc000; mask != 0; mask >>= 2) {
+ abridged_tw <<= 1;
+ // full TW uses 11 for empty registers, aTW uses 0
+ if ((tw & mask) != mask)
+ abridged_tw |= 1;
+ }
+ return abridged_tw;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h
index 27a1bad4d53f..76e004ce0ceb 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h
@@ -12,6 +12,7 @@
#include <cstddef>
#include <cstdint>
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/Support/Compiler.h"
@@ -239,10 +240,23 @@ enum {
// Generic floating-point registers
+LLVM_PACKED_START
+struct MMSRegComp {
+ uint64_t mantissa;
+ uint16_t sign_exp;
+};
+
struct MMSReg {
- uint8_t bytes[10];
+ union {
+ uint8_t bytes[10];
+ MMSRegComp comp;
+ };
uint8_t pad[6];
};
+LLVM_PACKED_END
+
+static_assert(sizeof(MMSRegComp) == 10, "MMSRegComp is not 10 bytes of size");
+static_assert(sizeof(MMSReg) == 16, "MMSReg is not 16 bytes of size");
struct XMMReg {
uint8_t bytes[16]; // 128-bits for each XMM register
@@ -369,6 +383,10 @@ inline void YMMToXState(const YMMReg& input, void* xmm_bytes, void* ymmh_bytes)
::memcpy(ymmh_bytes, input.bytes + sizeof(XMMReg), sizeof(YMMHReg));
}
+uint16_t AbridgedToFullTagWord(uint8_t abridged_tw, uint16_t sw,
+ llvm::ArrayRef<MMSReg> st_regs);
+uint8_t FullToAbridgedTagWord(uint16_t tw);
+
} // namespace lldb_private
#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp
index 8fc4d5282b06..17b96f944cda 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp
@@ -71,9 +71,87 @@ GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
}
}
+// Number of register sets provided by this context.
+enum {
+ k_num_gpr_registers = gpr_cpsr - gpr_r0 + 1,
+ k_num_fpr_registers = fpu_q15 - fpu_s0 + 1,
+ k_num_register_sets = 2
+};
+
+// arm general purpose registers.
+static const uint32_t g_gpr_regnums_arm[] = {
+ gpr_r0, gpr_r1,
+ gpr_r2, gpr_r3,
+ gpr_r4, gpr_r5,
+ gpr_r6, gpr_r7,
+ gpr_r8, gpr_r9,
+ gpr_r10, gpr_r11,
+ gpr_r12, gpr_sp,
+ gpr_lr, gpr_pc,
+ gpr_cpsr, LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) ==
+ k_num_gpr_registers,
+ "g_gpr_regnums_arm has wrong number of register infos");
+
+// arm floating point registers.
+static const uint32_t g_fpu_regnums_arm[] = {
+ fpu_s0, fpu_s1,
+ fpu_s2, fpu_s3,
+ fpu_s4, fpu_s5,
+ fpu_s6, fpu_s7,
+ fpu_s8, fpu_s9,
+ fpu_s10, fpu_s11,
+ fpu_s12, fpu_s13,
+ fpu_s14, fpu_s15,
+ fpu_s16, fpu_s17,
+ fpu_s18, fpu_s19,
+ fpu_s20, fpu_s21,
+ fpu_s22, fpu_s23,
+ fpu_s24, fpu_s25,
+ fpu_s26, fpu_s27,
+ fpu_s28, fpu_s29,
+ fpu_s30, fpu_s31,
+ fpu_fpscr, fpu_d0,
+ fpu_d1, fpu_d2,
+ fpu_d3, fpu_d4,
+ fpu_d5, fpu_d6,
+ fpu_d7, fpu_d8,
+ fpu_d9, fpu_d10,
+ fpu_d11, fpu_d12,
+ fpu_d13, fpu_d14,
+ fpu_d15, fpu_d16,
+ fpu_d17, fpu_d18,
+ fpu_d19, fpu_d20,
+ fpu_d21, fpu_d22,
+ fpu_d23, fpu_d24,
+ fpu_d25, fpu_d26,
+ fpu_d27, fpu_d28,
+ fpu_d29, fpu_d30,
+ fpu_d31, fpu_q0,
+ fpu_q1, fpu_q2,
+ fpu_q3, fpu_q4,
+ fpu_q5, fpu_q6,
+ fpu_q7, fpu_q8,
+ fpu_q9, fpu_q10,
+ fpu_q11, fpu_q12,
+ fpu_q13, fpu_q14,
+ fpu_q15, LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) ==
+ k_num_fpr_registers,
+ "g_fpu_regnums_arm has wrong number of register infos");
+
+// Register sets for arm.
+static const RegisterSet g_reg_sets_arm[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers,
+ g_gpr_regnums_arm},
+ {"Floating Point Registers", "fpu", k_num_fpr_registers,
+ g_fpu_regnums_arm}};
+
RegisterInfoPOSIX_arm::RegisterInfoPOSIX_arm(
const lldb_private::ArchSpec &target_arch)
- : lldb_private::RegisterInfoInterface(target_arch),
+ : lldb_private::RegisterInfoAndSetInterface(target_arch),
m_register_info_p(GetRegisterInfoPtr(target_arch)),
m_register_info_count(GetRegisterInfoCount(target_arch)) {}
@@ -81,11 +159,35 @@ size_t RegisterInfoPOSIX_arm::GetGPRSize() const {
return sizeof(struct RegisterInfoPOSIX_arm::GPR);
}
+size_t RegisterInfoPOSIX_arm::GetFPRSize() const {
+ return sizeof(struct RegisterInfoPOSIX_arm::FPU);
+}
+
const lldb_private::RegisterInfo *
RegisterInfoPOSIX_arm::GetRegisterInfo() const {
return m_register_info_p;
}
+size_t RegisterInfoPOSIX_arm::GetRegisterSetCount() const {
+ return k_num_register_sets;
+}
+
+size_t RegisterInfoPOSIX_arm::GetRegisterSetFromRegisterIndex(
+ uint32_t reg_index) const {
+ if (reg_index <= gpr_cpsr)
+ return GPRegSet;
+ if (reg_index <= fpu_q15)
+ return FPRegSet;
+ return LLDB_INVALID_REGNUM;
+}
+
+const lldb_private::RegisterSet *
+RegisterInfoPOSIX_arm::GetRegisterSet(size_t set_index) const {
+ if (set_index < GetRegisterSetCount())
+ return &g_reg_sets_arm[set_index];
+ return nullptr;
+}
+
uint32_t RegisterInfoPOSIX_arm::GetRegisterCount() const {
return m_register_info_count;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h
index 1cf896e3decf..db155d757ca8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.h
@@ -9,12 +9,14 @@
#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM_H
#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM_H
-#include "RegisterInfoInterface.h"
+#include "RegisterInfoAndSetInterface.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
-class RegisterInfoPOSIX_arm : public lldb_private::RegisterInfoInterface {
+class RegisterInfoPOSIX_arm : public lldb_private::RegisterInfoAndSetInterface {
public:
+ enum { GPRegSet = 0, FPRegSet};
+
struct GPR {
uint32_t r[16]; // R0-R15
uint32_t cpsr; // CPSR
@@ -49,10 +51,19 @@ public:
size_t GetGPRSize() const override;
+ size_t GetFPRSize() const override;
+
const lldb_private::RegisterInfo *GetRegisterInfo() const override;
uint32_t GetRegisterCount() const override;
+ const lldb_private::RegisterSet *
+ GetRegisterSet(size_t reg_set) const override;
+
+ size_t GetRegisterSetCount() const override;
+
+ size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override;
+
private:
const lldb_private::RegisterInfo *m_register_info_p;
uint32_t m_register_info_count;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
index 4537cee42ad9..515c9f44e1e2 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
@@ -25,6 +25,24 @@
(LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::FPU, reg) + \
sizeof(RegisterInfoPOSIX_arm64::GPR))
+// This information is based on AArch64 with SVE architecture reference manual.
+// AArch64 with SVE has 32 Z and 16 P vector registers. There is also an FFR
+// (First Fault) register and a VG (Vector Granule) pseudo register.
+
+// SVE 16-byte quad word is the basic unit of expansion in vector length.
+#define SVE_QUAD_WORD_BYTES 16
+
+// Vector length is the multiplier which decides the no of quad words,
+// (multiples of 128-bits or 16-bytes) present in a Z register. Vector length
+// is decided during execution and can change at runtime. SVE AArch64 register
+// infos have modes one for each valid value of vector length. A change in
+// vector length requires register context to update sizes of SVE Z, P and FFR.
+// Also register context needs to update byte offsets of all registers affected
+// by the change in vector length.
+#define SVE_REGS_DEFAULT_OFFSET_LINUX sizeof(RegisterInfoPOSIX_arm64::GPR)
+
+#define SVE_OFFSET_VG SVE_REGS_DEFAULT_OFFSET_LINUX
+
#define EXC_OFFSET_NAME(reg) \
(LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm64::EXC, reg) + \
sizeof(RegisterInfoPOSIX_arm64::GPR) + \
@@ -51,6 +69,7 @@
// Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure.
#define DECLARE_REGISTER_INFOS_ARM64_STRUCT
#include "RegisterInfos_arm64.h"
+#include "RegisterInfos_arm64_sve.h"
#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
static const lldb_private::RegisterInfo *
@@ -69,7 +88,8 @@ GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
enum {
k_num_gpr_registers = gpr_w28 - gpr_x0 + 1,
k_num_fpr_registers = fpu_fpcr - fpu_v0 + 1,
- k_num_register_sets = 2
+ k_num_sve_registers = sve_ffr - sve_vg + 1,
+ k_num_register_sets = 3
};
// ARM64 general purpose registers.
@@ -133,13 +153,38 @@ static const uint32_t g_fpu_regnums_arm64[] = {
static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) -
1) == k_num_fpr_registers,
"g_fpu_regnums_arm64 has wrong number of register infos");
-// clang-format on
+
+// ARM64 SVE registers.
+static const uint32_t g_sve_regnums_arm64[] = {
+ sve_vg, sve_z0, sve_z1,
+ sve_z2, sve_z3, sve_z4,
+ sve_z5, sve_z6, sve_z7,
+ sve_z8, sve_z9, sve_z10,
+ sve_z11, sve_z12, sve_z13,
+ sve_z14, sve_z15, sve_z16,
+ sve_z17, sve_z18, sve_z19,
+ sve_z20, sve_z21, sve_z22,
+ sve_z23, sve_z24, sve_z25,
+ sve_z26, sve_z27, sve_z28,
+ sve_z29, sve_z30, sve_z31,
+ sve_p0, sve_p1, sve_p2,
+ sve_p3, sve_p4, sve_p5,
+ sve_p6, sve_p7, sve_p8,
+ sve_p9, sve_p10, sve_p11,
+ sve_p12, sve_p13, sve_p14,
+ sve_p15, sve_ffr, LLDB_INVALID_REGNUM};
+static_assert(((sizeof g_sve_regnums_arm64 / sizeof g_sve_regnums_arm64[0]) -
+ 1) == k_num_sve_registers,
+ "g_sve_regnums_arm64 has wrong number of register infos");
+
// Register sets for ARM64.
static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = {
{"General Purpose Registers", "gpr", k_num_gpr_registers,
g_gpr_regnums_arm64},
{"Floating Point Registers", "fpu", k_num_fpr_registers,
- g_fpu_regnums_arm64}};
+ g_fpu_regnums_arm64},
+ {"Scalable Vector Extension Registers", "sve", k_num_sve_registers,
+ g_sve_regnums_arm64}};
static uint32_t
GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
@@ -159,25 +204,13 @@ RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64(
: lldb_private::RegisterInfoAndSetInterface(target_arch),
m_register_info_p(GetRegisterInfoPtr(target_arch)),
m_register_info_count(GetRegisterInfoCount(target_arch)) {
-
- switch (target_arch.GetMachine()) {
- case llvm::Triple::aarch64:
- case llvm::Triple::aarch64_32:
- num_registers = k_num_gpr_registers + k_num_fpr_registers;
- num_gpr_registers = k_num_gpr_registers;
- num_fpr_registers = k_num_fpr_registers;
- last_gpr = gpr_w28;
- first_fpr = fpu_v0;
- last_fpr = fpu_fpcr;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
}
uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const {
- return num_gpr_registers + num_fpr_registers;
+ if (IsSVEEnabled())
+ return k_num_gpr_registers + k_num_fpr_registers + k_num_sve_registers;
+
+ return k_num_gpr_registers + k_num_fpr_registers;
}
size_t RegisterInfoPOSIX_arm64::GetGPRSize() const {
@@ -194,22 +227,120 @@ RegisterInfoPOSIX_arm64::GetRegisterInfo() const {
}
size_t RegisterInfoPOSIX_arm64::GetRegisterSetCount() const {
- return k_num_register_sets;
+ if (IsSVEEnabled())
+ return k_num_register_sets;
+ return k_num_register_sets - 1;
}
size_t RegisterInfoPOSIX_arm64::GetRegisterSetFromRegisterIndex(
uint32_t reg_index) const {
- if (reg_index <= last_gpr)
+ if (reg_index <= gpr_w28)
return GPRegSet;
- else if (reg_index <= last_fpr)
+ if (reg_index <= fpu_fpcr)
return FPRegSet;
+ if (reg_index <= sve_ffr)
+ return SVERegSet;
return LLDB_INVALID_REGNUM;
}
const lldb_private::RegisterSet *
RegisterInfoPOSIX_arm64::GetRegisterSet(size_t set_index) const {
- if (set_index < k_num_register_sets)
+ if (set_index < GetRegisterSetCount())
return &g_reg_sets_arm64[set_index];
-
return nullptr;
}
+
+uint32_t
+RegisterInfoPOSIX_arm64::ConfigureVectorRegisterInfos(uint32_t sve_vq) {
+ // sve_vq contains SVE Quad vector length in context of AArch64 SVE.
+ // SVE register infos if enabled cannot be disabled by selecting sve_vq = 0.
+ // Also if an invalid or previously set vector length is passed to this
+ // function then it will exit immediately with previously set vector length.
+ if (!VectorSizeIsValid(sve_vq) || m_vector_reg_vq == sve_vq)
+ return m_vector_reg_vq;
+
+ // We cannot enable AArch64 only mode if SVE was enabled.
+ if (sve_vq == eVectorQuadwordAArch64 &&
+ m_vector_reg_vq > eVectorQuadwordAArch64)
+ sve_vq = eVectorQuadwordAArch64SVE;
+
+ m_vector_reg_vq = sve_vq;
+
+ if (sve_vq == eVectorQuadwordAArch64) {
+ m_register_info_count =
+ static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) /
+ sizeof(g_register_infos_arm64_le[0]));
+ m_register_info_p = g_register_infos_arm64_le;
+
+ return m_vector_reg_vq;
+ }
+
+ m_register_info_count =
+ static_cast<uint32_t>(sizeof(g_register_infos_arm64_sve_le) /
+ sizeof(g_register_infos_arm64_sve_le[0]));
+
+ std::vector<lldb_private::RegisterInfo> &reg_info_ref =
+ m_per_vq_reg_infos[sve_vq];
+
+ if (reg_info_ref.empty()) {
+ reg_info_ref = llvm::makeArrayRef(g_register_infos_arm64_sve_le,
+ m_register_info_count);
+
+ uint32_t offset = SVE_REGS_DEFAULT_OFFSET_LINUX;
+
+ reg_info_ref[fpu_fpsr].byte_offset = offset;
+ reg_info_ref[fpu_fpcr].byte_offset = offset + 4;
+ reg_info_ref[sve_vg].byte_offset = offset + 8;
+ offset += 16;
+
+ // Update Z registers size and offset
+ uint32_t s_reg_base = fpu_s0;
+ uint32_t d_reg_base = fpu_d0;
+ uint32_t v_reg_base = fpu_v0;
+ uint32_t z_reg_base = sve_z0;
+
+ for (uint32_t index = 0; index < 32; index++) {
+ reg_info_ref[s_reg_base + index].byte_offset = offset;
+ reg_info_ref[d_reg_base + index].byte_offset = offset;
+ reg_info_ref[v_reg_base + index].byte_offset = offset;
+ reg_info_ref[z_reg_base + index].byte_offset = offset;
+
+ reg_info_ref[z_reg_base + index].byte_size = sve_vq * SVE_QUAD_WORD_BYTES;
+ offset += reg_info_ref[z_reg_base + index].byte_size;
+ }
+
+ // Update P registers and FFR size and offset
+ for (uint32_t it = sve_p0; it <= sve_ffr; it++) {
+ reg_info_ref[it].byte_offset = offset;
+ reg_info_ref[it].byte_size = sve_vq * SVE_QUAD_WORD_BYTES / 8;
+ offset += reg_info_ref[it].byte_size;
+ }
+
+ m_per_vq_reg_infos[sve_vq] = reg_info_ref;
+ }
+
+ m_register_info_p = reg_info_ref.data();
+ return m_vector_reg_vq;
+}
+
+bool RegisterInfoPOSIX_arm64::IsSVEZReg(unsigned reg) const {
+ return (sve_z0 <= reg && reg <= sve_z31);
+}
+
+bool RegisterInfoPOSIX_arm64::IsSVEPReg(unsigned reg) const {
+ return (sve_p0 <= reg && reg <= sve_p15);
+}
+
+bool RegisterInfoPOSIX_arm64::IsSVERegVG(unsigned reg) const {
+ return sve_vg == reg;
+}
+
+uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEZ0() const { return sve_z0; }
+
+uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEFFR() const { return sve_ffr; }
+
+uint32_t RegisterInfoPOSIX_arm64::GetRegNumFPCR() const { return fpu_fpcr; }
+
+uint32_t RegisterInfoPOSIX_arm64::GetRegNumFPSR() const { return fpu_fpsr; }
+
+uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEVG() const { return sve_vg; }
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
index 2da6a531a6b6..2929f2009dd9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
@@ -12,13 +12,24 @@
#include "RegisterInfoAndSetInterface.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
+#include <map>
+
+enum class SVEState { Unknown, Disabled, FPSIMD, Full };
class RegisterInfoPOSIX_arm64
: public lldb_private::RegisterInfoAndSetInterface {
public:
- enum { GPRegSet = 0, FPRegSet };
+ enum { GPRegSet = 0, FPRegSet, SVERegSet };
+
+ // AArch64 Register set FP/SIMD feature configuration
+ enum {
+ eVectorQuadwordAArch64,
+ eVectorQuadwordAArch64SVE,
+ eVectorQuadwordAArch64SVEMax = 256
+ };
// based on RegisterContextDarwin_arm64.h
+ LLVM_PACKED_START
struct GPR {
uint64_t x[29]; // x0-x28
uint64_t fp; // x29
@@ -27,6 +38,7 @@ public:
uint64_t pc; // pc
uint32_t cpsr; // cpsr
};
+ LLVM_PACKED_END
// based on RegisterContextDarwin_arm64.h
struct VReg {
@@ -73,14 +85,33 @@ public:
size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override;
+ uint32_t ConfigureVectorRegisterInfos(uint32_t sve_vq);
+
+ bool VectorSizeIsValid(uint32_t vq) {
+ if (vq >= eVectorQuadwordAArch64 && vq <= eVectorQuadwordAArch64SVEMax)
+ return true;
+ return false;
+ }
+
+ bool IsSVEEnabled() const { return m_vector_reg_vq > eVectorQuadwordAArch64; }
+
+ bool IsSVEZReg(unsigned reg) const;
+ bool IsSVEPReg(unsigned reg) const;
+ bool IsSVERegVG(unsigned reg) const;
+
+ uint32_t GetRegNumSVEZ0() const;
+ uint32_t GetRegNumSVEFFR() const;
+ uint32_t GetRegNumFPCR() const;
+ uint32_t GetRegNumFPSR() const;
+ uint32_t GetRegNumSVEVG() const;
+
private:
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
+ typedef std::map<uint32_t, std::vector<lldb_private::RegisterInfo>>
+ per_vq_register_infos;
+
+ per_vq_register_infos m_per_vq_reg_infos;
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
+ uint32_t m_vector_reg_vq = eVectorQuadwordAArch64;
const lldb_private::RegisterInfo *m_register_info_p;
uint32_t m_register_info_count;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h
new file mode 100644
index 000000000000..9551db7e8ebf
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h
@@ -0,0 +1,572 @@
+//===-- RegisterInfos_arm64_sve.h -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifdef DECLARE_REGISTER_INFOS_ARM64_STRUCT
+
+enum {
+ sve_vg = exc_far,
+
+ sve_z0,
+ sve_z1,
+ sve_z2,
+ sve_z3,
+ sve_z4,
+ sve_z5,
+ sve_z6,
+ sve_z7,
+ sve_z8,
+ sve_z9,
+ sve_z10,
+ sve_z11,
+ sve_z12,
+ sve_z13,
+ sve_z14,
+ sve_z15,
+ sve_z16,
+ sve_z17,
+ sve_z18,
+ sve_z19,
+ sve_z20,
+ sve_z21,
+ sve_z22,
+ sve_z23,
+ sve_z24,
+ sve_z25,
+ sve_z26,
+ sve_z27,
+ sve_z28,
+ sve_z29,
+ sve_z30,
+ sve_z31,
+
+ sve_p0,
+ sve_p1,
+ sve_p2,
+ sve_p3,
+ sve_p4,
+ sve_p5,
+ sve_p6,
+ sve_p7,
+ sve_p8,
+ sve_p9,
+ sve_p10,
+ sve_p11,
+ sve_p12,
+ sve_p13,
+ sve_p14,
+ sve_p15,
+
+ sve_ffr,
+};
+
+#ifndef SVE_OFFSET_VG
+#error SVE_OFFSET_VG must be defined before including this header file
+#endif
+
+static uint32_t g_sve_s0_invalidates[] = {sve_z0, fpu_v0, fpu_d0,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s1_invalidates[] = {sve_z1, fpu_v1, fpu_d1,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s2_invalidates[] = {sve_z2, fpu_v2, fpu_d2,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s3_invalidates[] = {sve_z3, fpu_v3, fpu_d3,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s4_invalidates[] = {sve_z4, fpu_v4, fpu_d4,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s5_invalidates[] = {sve_z5, fpu_v5, fpu_d5,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s6_invalidates[] = {sve_z6, fpu_v6, fpu_d6,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s7_invalidates[] = {sve_z7, fpu_v7, fpu_d7,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s8_invalidates[] = {sve_z8, fpu_v8, fpu_d8,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s9_invalidates[] = {sve_z9, fpu_v9, fpu_d9,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s10_invalidates[] = {sve_z10, fpu_v10, fpu_d10,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s11_invalidates[] = {sve_z11, fpu_v11, fpu_d11,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s12_invalidates[] = {sve_z12, fpu_v12, fpu_d12,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s13_invalidates[] = {sve_z13, fpu_v13, fpu_d13,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s14_invalidates[] = {sve_z14, fpu_v14, fpu_d14,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s15_invalidates[] = {sve_z15, fpu_v15, fpu_d15,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s16_invalidates[] = {sve_z16, fpu_v16, fpu_d16,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s17_invalidates[] = {sve_z17, fpu_v17, fpu_d17,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s18_invalidates[] = {sve_z18, fpu_v18, fpu_d18,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s19_invalidates[] = {sve_z19, fpu_v19, fpu_d19,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s20_invalidates[] = {sve_z20, fpu_v20, fpu_d20,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s21_invalidates[] = {sve_z21, fpu_v21, fpu_d21,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s22_invalidates[] = {sve_z22, fpu_v22, fpu_d22,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s23_invalidates[] = {sve_z23, fpu_v23, fpu_d23,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s24_invalidates[] = {sve_z24, fpu_v24, fpu_d24,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s25_invalidates[] = {sve_z25, fpu_v25, fpu_d25,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s26_invalidates[] = {sve_z26, fpu_v26, fpu_d26,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s27_invalidates[] = {sve_z27, fpu_v27, fpu_d27,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s28_invalidates[] = {sve_z28, fpu_v28, fpu_d28,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s29_invalidates[] = {sve_z29, fpu_v29, fpu_d29,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s30_invalidates[] = {sve_z30, fpu_v30, fpu_d30,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_s31_invalidates[] = {sve_z31, fpu_v31, fpu_d31,
+ LLDB_INVALID_REGNUM};
+
+static uint32_t g_sve_d0_invalidates[] = {sve_z0, fpu_v0, fpu_s0,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d1_invalidates[] = {sve_z1, fpu_v1, fpu_s1,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d2_invalidates[] = {sve_z2, fpu_v2, fpu_s2,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d3_invalidates[] = {sve_z3, fpu_v3, fpu_s3,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d4_invalidates[] = {sve_z4, fpu_v4, fpu_s4,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d5_invalidates[] = {sve_z5, fpu_v5, fpu_s5,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d6_invalidates[] = {sve_z6, fpu_v6, fpu_s6,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d7_invalidates[] = {sve_z7, fpu_v7, fpu_s7,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d8_invalidates[] = {sve_z8, fpu_v8, fpu_s8,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d9_invalidates[] = {sve_z9, fpu_v9, fpu_s9,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d10_invalidates[] = {sve_z10, fpu_v10, fpu_s10,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d11_invalidates[] = {sve_z11, fpu_v11, fpu_s11,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d12_invalidates[] = {sve_z12, fpu_v12, fpu_s12,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d13_invalidates[] = {sve_z13, fpu_v13, fpu_s13,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d14_invalidates[] = {sve_z14, fpu_v14, fpu_s14,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d15_invalidates[] = {sve_z15, fpu_v15, fpu_s15,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d16_invalidates[] = {sve_z16, fpu_v16, fpu_s16,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d17_invalidates[] = {sve_z17, fpu_v17, fpu_s17,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d18_invalidates[] = {sve_z18, fpu_v18, fpu_s18,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d19_invalidates[] = {sve_z19, fpu_v19, fpu_s19,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d20_invalidates[] = {sve_z20, fpu_v20, fpu_s20,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d21_invalidates[] = {sve_z21, fpu_v21, fpu_s21,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d22_invalidates[] = {sve_z22, fpu_v22, fpu_s22,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d23_invalidates[] = {sve_z23, fpu_v23, fpu_s23,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d24_invalidates[] = {sve_z24, fpu_v24, fpu_s24,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d25_invalidates[] = {sve_z25, fpu_v25, fpu_s25,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d26_invalidates[] = {sve_z26, fpu_v26, fpu_s26,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d27_invalidates[] = {sve_z27, fpu_v27, fpu_s27,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d28_invalidates[] = {sve_z28, fpu_v28, fpu_s28,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d29_invalidates[] = {sve_z29, fpu_v29, fpu_s29,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d30_invalidates[] = {sve_z30, fpu_v30, fpu_s30,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_d31_invalidates[] = {sve_z31, fpu_v31, fpu_s31,
+ LLDB_INVALID_REGNUM};
+
+static uint32_t g_sve_v0_invalidates[] = {sve_z0, fpu_d0, fpu_s0,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v1_invalidates[] = {sve_z1, fpu_d1, fpu_s1,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v2_invalidates[] = {sve_z2, fpu_d2, fpu_s2,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v3_invalidates[] = {sve_z3, fpu_d3, fpu_s3,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v4_invalidates[] = {sve_z4, fpu_d4, fpu_s4,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v5_invalidates[] = {sve_z5, fpu_d5, fpu_s5,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v6_invalidates[] = {sve_z6, fpu_d6, fpu_s6,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v7_invalidates[] = {sve_z7, fpu_d7, fpu_s7,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v8_invalidates[] = {sve_z8, fpu_d8, fpu_s8,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v9_invalidates[] = {sve_z9, fpu_d9, fpu_s9,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v10_invalidates[] = {sve_z10, fpu_d10, fpu_s10,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v11_invalidates[] = {sve_z11, fpu_d11, fpu_s11,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v12_invalidates[] = {sve_z12, fpu_d12, fpu_s12,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v13_invalidates[] = {sve_z13, fpu_d13, fpu_s13,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v14_invalidates[] = {sve_z14, fpu_d14, fpu_s14,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v15_invalidates[] = {sve_z15, fpu_d15, fpu_s15,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v16_invalidates[] = {sve_z16, fpu_d16, fpu_s16,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v17_invalidates[] = {sve_z17, fpu_d17, fpu_s17,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v18_invalidates[] = {sve_z18, fpu_d18, fpu_s18,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v19_invalidates[] = {sve_z19, fpu_d19, fpu_s19,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v20_invalidates[] = {sve_z20, fpu_d20, fpu_s20,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v21_invalidates[] = {sve_z21, fpu_d21, fpu_s21,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v22_invalidates[] = {sve_z22, fpu_d22, fpu_s22,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v23_invalidates[] = {sve_z23, fpu_d23, fpu_s23,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v24_invalidates[] = {sve_z24, fpu_d24, fpu_s24,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v25_invalidates[] = {sve_z25, fpu_d25, fpu_s25,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v26_invalidates[] = {sve_z26, fpu_d26, fpu_s26,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v27_invalidates[] = {sve_z27, fpu_d27, fpu_s27,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v28_invalidates[] = {sve_z28, fpu_d28, fpu_s28,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v29_invalidates[] = {sve_z29, fpu_d29, fpu_s29,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v30_invalidates[] = {sve_z30, fpu_d30, fpu_s30,
+ LLDB_INVALID_REGNUM};
+static uint32_t g_sve_v31_invalidates[] = {sve_z31, fpu_d31, fpu_s31,
+ LLDB_INVALID_REGNUM};
+
+static uint32_t g_contained_z0[] = {sve_z0, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z1[] = {sve_z1, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z2[] = {sve_z2, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z3[] = {sve_z3, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z4[] = {sve_z4, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z5[] = {sve_z5, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z6[] = {sve_z6, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z7[] = {sve_z7, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z8[] = {sve_z8, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z9[] = {sve_z9, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z10[] = {sve_z10, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z11[] = {sve_z11, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z12[] = {sve_z12, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z13[] = {sve_z13, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z14[] = {sve_z14, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z15[] = {sve_z15, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z16[] = {sve_z16, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z17[] = {sve_z17, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z18[] = {sve_z18, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z19[] = {sve_z19, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z20[] = {sve_z20, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z21[] = {sve_z21, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z22[] = {sve_z22, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z23[] = {sve_z23, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z24[] = {sve_z24, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z25[] = {sve_z25, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z26[] = {sve_z26, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z27[] = {sve_z27, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z28[] = {sve_z28, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z29[] = {sve_z29, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z30[] = {sve_z30, LLDB_INVALID_REGNUM};
+static uint32_t g_contained_z31[] = {sve_z31, LLDB_INVALID_REGNUM};
+
+#define VG_OFFSET_NAME(reg) SVE_OFFSET_VG
+
+#define SVE_REG_KIND(reg) MISC_KIND(reg, sve, LLDB_INVALID_REGNUM)
+#define MISC_VG_KIND(lldb_kind) MISC_KIND(vg, sve, LLDB_INVALID_REGNUM)
+
+// Default offset SVE Z registers and all corresponding pseudo registers
+// ( S, D and V registers) is zero and will be configured during execution.
+
+// Defines sve pseudo vector (V) register with 16-byte size
+#define DEFINE_VREG_SVE(vreg, zreg) \
+ { \
+ #vreg, nullptr, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, \
+ VREG_KIND(vreg), g_contained_##zreg, g_sve_##vreg##_invalidates, \
+ nullptr, 0 \
+ }
+
+// Defines S and D pseudo registers mapping over corresponding vector register
+#define DEFINE_FPU_PSEUDO_SVE(reg, size, zreg) \
+ { \
+ #reg, nullptr, size, 0, lldb::eEncodingIEEE754, lldb::eFormatFloat, \
+ LLDB_KIND(fpu_##reg), g_contained_##zreg, g_sve_##reg##_invalidates, \
+ nullptr, 0 \
+ }
+
+// Defines a Z vector register with 16-byte default size
+#define DEFINE_ZREG(reg) \
+ { \
+ #reg, nullptr, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, \
+ SVE_REG_KIND(reg), nullptr, nullptr, nullptr, 0 \
+ }
+
+// Defines a P vector register with 2-byte default size
+#define DEFINE_PREG(reg) \
+ { \
+ #reg, nullptr, 2, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, \
+ SVE_REG_KIND(reg), nullptr, nullptr, nullptr, 0 \
+ }
+
+static lldb_private::RegisterInfo g_register_infos_arm64_sve_le[] = {
+ // clang-format off
+ // DEFINE_GPR64(name, GENERIC KIND)
+ DEFINE_GPR64(x0, LLDB_REGNUM_GENERIC_ARG1),
+ DEFINE_GPR64(x1, LLDB_REGNUM_GENERIC_ARG2),
+ DEFINE_GPR64(x2, LLDB_REGNUM_GENERIC_ARG3),
+ DEFINE_GPR64(x3, LLDB_REGNUM_GENERIC_ARG4),
+ DEFINE_GPR64(x4, LLDB_REGNUM_GENERIC_ARG5),
+ DEFINE_GPR64(x5, LLDB_REGNUM_GENERIC_ARG6),
+ DEFINE_GPR64(x6, LLDB_REGNUM_GENERIC_ARG7),
+ DEFINE_GPR64(x7, LLDB_REGNUM_GENERIC_ARG8),
+ DEFINE_GPR64(x8, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x9, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x10, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x11, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x12, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x13, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x14, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x15, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x16, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x17, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x18, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x19, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x20, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x21, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x22, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x23, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x24, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x25, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x26, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x27, LLDB_INVALID_REGNUM),
+ DEFINE_GPR64(x28, LLDB_INVALID_REGNUM),
+ // DEFINE_GPR64(name, GENERIC KIND)
+ DEFINE_GPR64_ALT(fp, x29, LLDB_REGNUM_GENERIC_FP),
+ DEFINE_GPR64_ALT(lr, x30, LLDB_REGNUM_GENERIC_RA),
+ DEFINE_GPR64_ALT(sp, x31, LLDB_REGNUM_GENERIC_SP),
+ DEFINE_GPR64(pc, LLDB_REGNUM_GENERIC_PC),
+
+ // DEFINE_MISC_REGS(name, size, TYPE, lldb kind)
+ DEFINE_MISC_REGS(cpsr, 4, GPR, gpr_cpsr),
+
+ // DEFINE_GPR32(name, parent name)
+ DEFINE_GPR32(w0, x0),
+ DEFINE_GPR32(w1, x1),
+ DEFINE_GPR32(w2, x2),
+ DEFINE_GPR32(w3, x3),
+ DEFINE_GPR32(w4, x4),
+ DEFINE_GPR32(w5, x5),
+ DEFINE_GPR32(w6, x6),
+ DEFINE_GPR32(w7, x7),
+ DEFINE_GPR32(w8, x8),
+ DEFINE_GPR32(w9, x9),
+ DEFINE_GPR32(w10, x10),
+ DEFINE_GPR32(w11, x11),
+ DEFINE_GPR32(w12, x12),
+ DEFINE_GPR32(w13, x13),
+ DEFINE_GPR32(w14, x14),
+ DEFINE_GPR32(w15, x15),
+ DEFINE_GPR32(w16, x16),
+ DEFINE_GPR32(w17, x17),
+ DEFINE_GPR32(w18, x18),
+ DEFINE_GPR32(w19, x19),
+ DEFINE_GPR32(w20, x20),
+ DEFINE_GPR32(w21, x21),
+ DEFINE_GPR32(w22, x22),
+ DEFINE_GPR32(w23, x23),
+ DEFINE_GPR32(w24, x24),
+ DEFINE_GPR32(w25, x25),
+ DEFINE_GPR32(w26, x26),
+ DEFINE_GPR32(w27, x27),
+ DEFINE_GPR32(w28, x28),
+
+ // DEFINE_VREG_SVE(v register, z register)
+ DEFINE_VREG_SVE(v0, z0),
+ DEFINE_VREG_SVE(v1, z1),
+ DEFINE_VREG_SVE(v2, z2),
+ DEFINE_VREG_SVE(v3, z3),
+ DEFINE_VREG_SVE(v4, z4),
+ DEFINE_VREG_SVE(v5, z5),
+ DEFINE_VREG_SVE(v6, z6),
+ DEFINE_VREG_SVE(v7, z7),
+ DEFINE_VREG_SVE(v8, z8),
+ DEFINE_VREG_SVE(v9, z9),
+ DEFINE_VREG_SVE(v10, z10),
+ DEFINE_VREG_SVE(v11, z11),
+ DEFINE_VREG_SVE(v12, z12),
+ DEFINE_VREG_SVE(v13, z13),
+ DEFINE_VREG_SVE(v14, z14),
+ DEFINE_VREG_SVE(v15, z15),
+ DEFINE_VREG_SVE(v16, z16),
+ DEFINE_VREG_SVE(v17, z17),
+ DEFINE_VREG_SVE(v18, z18),
+ DEFINE_VREG_SVE(v19, z19),
+ DEFINE_VREG_SVE(v20, z20),
+ DEFINE_VREG_SVE(v21, z21),
+ DEFINE_VREG_SVE(v22, z22),
+ DEFINE_VREG_SVE(v23, z23),
+ DEFINE_VREG_SVE(v24, z24),
+ DEFINE_VREG_SVE(v25, z25),
+ DEFINE_VREG_SVE(v26, z26),
+ DEFINE_VREG_SVE(v27, z27),
+ DEFINE_VREG_SVE(v28, z28),
+ DEFINE_VREG_SVE(v29, z29),
+ DEFINE_VREG_SVE(v30, z30),
+ DEFINE_VREG_SVE(v31, z31),
+
+ // DEFINE_FPU_PSEUDO(name, size, ENDIAN OFFSET, parent register)
+ DEFINE_FPU_PSEUDO_SVE(s0, 4, z0),
+ DEFINE_FPU_PSEUDO_SVE(s1, 4, z1),
+ DEFINE_FPU_PSEUDO_SVE(s2, 4, z2),
+ DEFINE_FPU_PSEUDO_SVE(s3, 4, z3),
+ DEFINE_FPU_PSEUDO_SVE(s4, 4, z4),
+ DEFINE_FPU_PSEUDO_SVE(s5, 4, z5),
+ DEFINE_FPU_PSEUDO_SVE(s6, 4, z6),
+ DEFINE_FPU_PSEUDO_SVE(s7, 4, z7),
+ DEFINE_FPU_PSEUDO_SVE(s8, 4, z8),
+ DEFINE_FPU_PSEUDO_SVE(s9, 4, z9),
+ DEFINE_FPU_PSEUDO_SVE(s10, 4, z10),
+ DEFINE_FPU_PSEUDO_SVE(s11, 4, z11),
+ DEFINE_FPU_PSEUDO_SVE(s12, 4, z12),
+ DEFINE_FPU_PSEUDO_SVE(s13, 4, z13),
+ DEFINE_FPU_PSEUDO_SVE(s14, 4, z14),
+ DEFINE_FPU_PSEUDO_SVE(s15, 4, z15),
+ DEFINE_FPU_PSEUDO_SVE(s16, 4, z16),
+ DEFINE_FPU_PSEUDO_SVE(s17, 4, z17),
+ DEFINE_FPU_PSEUDO_SVE(s18, 4, z18),
+ DEFINE_FPU_PSEUDO_SVE(s19, 4, z19),
+ DEFINE_FPU_PSEUDO_SVE(s20, 4, z20),
+ DEFINE_FPU_PSEUDO_SVE(s21, 4, z21),
+ DEFINE_FPU_PSEUDO_SVE(s22, 4, z22),
+ DEFINE_FPU_PSEUDO_SVE(s23, 4, z23),
+ DEFINE_FPU_PSEUDO_SVE(s24, 4, z24),
+ DEFINE_FPU_PSEUDO_SVE(s25, 4, z25),
+ DEFINE_FPU_PSEUDO_SVE(s26, 4, z26),
+ DEFINE_FPU_PSEUDO_SVE(s27, 4, z27),
+ DEFINE_FPU_PSEUDO_SVE(s28, 4, z28),
+ DEFINE_FPU_PSEUDO_SVE(s29, 4, z29),
+ DEFINE_FPU_PSEUDO_SVE(s30, 4, z30),
+ DEFINE_FPU_PSEUDO_SVE(s31, 4, z31),
+
+ DEFINE_FPU_PSEUDO_SVE(d0, 8, z0),
+ DEFINE_FPU_PSEUDO_SVE(d1, 8, z1),
+ DEFINE_FPU_PSEUDO_SVE(d2, 8, z2),
+ DEFINE_FPU_PSEUDO_SVE(d3, 8, z3),
+ DEFINE_FPU_PSEUDO_SVE(d4, 8, z4),
+ DEFINE_FPU_PSEUDO_SVE(d5, 8, z5),
+ DEFINE_FPU_PSEUDO_SVE(d6, 8, z6),
+ DEFINE_FPU_PSEUDO_SVE(d7, 8, z7),
+ DEFINE_FPU_PSEUDO_SVE(d8, 8, z8),
+ DEFINE_FPU_PSEUDO_SVE(d9, 8, z9),
+ DEFINE_FPU_PSEUDO_SVE(d10, 8, z10),
+ DEFINE_FPU_PSEUDO_SVE(d11, 8, z11),
+ DEFINE_FPU_PSEUDO_SVE(d12, 8, z12),
+ DEFINE_FPU_PSEUDO_SVE(d13, 8, z13),
+ DEFINE_FPU_PSEUDO_SVE(d14, 8, z14),
+ DEFINE_FPU_PSEUDO_SVE(d15, 8, z15),
+ DEFINE_FPU_PSEUDO_SVE(d16, 8, z16),
+ DEFINE_FPU_PSEUDO_SVE(d17, 8, z17),
+ DEFINE_FPU_PSEUDO_SVE(d18, 8, z18),
+ DEFINE_FPU_PSEUDO_SVE(d19, 8, z19),
+ DEFINE_FPU_PSEUDO_SVE(d20, 8, z20),
+ DEFINE_FPU_PSEUDO_SVE(d21, 8, z21),
+ DEFINE_FPU_PSEUDO_SVE(d22, 8, z22),
+ DEFINE_FPU_PSEUDO_SVE(d23, 8, z23),
+ DEFINE_FPU_PSEUDO_SVE(d24, 8, z24),
+ DEFINE_FPU_PSEUDO_SVE(d25, 8, z25),
+ DEFINE_FPU_PSEUDO_SVE(d26, 8, z26),
+ DEFINE_FPU_PSEUDO_SVE(d27, 8, z27),
+ DEFINE_FPU_PSEUDO_SVE(d28, 8, z28),
+ DEFINE_FPU_PSEUDO_SVE(d29, 8, z29),
+ DEFINE_FPU_PSEUDO_SVE(d30, 8, z30),
+ DEFINE_FPU_PSEUDO_SVE(d31, 8, z31),
+
+ // DEFINE_MISC_REGS(name, size, TYPE, lldb kind)
+ DEFINE_MISC_REGS(fpsr, 4, FPU, fpu_fpsr),
+ DEFINE_MISC_REGS(fpcr, 4, FPU, fpu_fpcr),
+
+ DEFINE_MISC_REGS(vg, 8, VG, sve_vg),
+ // DEFINE_ZREG(name)
+ DEFINE_ZREG(z0),
+ DEFINE_ZREG(z1),
+ DEFINE_ZREG(z2),
+ DEFINE_ZREG(z3),
+ DEFINE_ZREG(z4),
+ DEFINE_ZREG(z5),
+ DEFINE_ZREG(z6),
+ DEFINE_ZREG(z7),
+ DEFINE_ZREG(z8),
+ DEFINE_ZREG(z9),
+ DEFINE_ZREG(z10),
+ DEFINE_ZREG(z11),
+ DEFINE_ZREG(z12),
+ DEFINE_ZREG(z13),
+ DEFINE_ZREG(z14),
+ DEFINE_ZREG(z15),
+ DEFINE_ZREG(z16),
+ DEFINE_ZREG(z17),
+ DEFINE_ZREG(z18),
+ DEFINE_ZREG(z19),
+ DEFINE_ZREG(z20),
+ DEFINE_ZREG(z21),
+ DEFINE_ZREG(z22),
+ DEFINE_ZREG(z23),
+ DEFINE_ZREG(z24),
+ DEFINE_ZREG(z25),
+ DEFINE_ZREG(z26),
+ DEFINE_ZREG(z27),
+ DEFINE_ZREG(z28),
+ DEFINE_ZREG(z29),
+ DEFINE_ZREG(z30),
+ DEFINE_ZREG(z31),
+
+ // DEFINE_PREG(name)
+ DEFINE_PREG(p0),
+ DEFINE_PREG(p1),
+ DEFINE_PREG(p2),
+ DEFINE_PREG(p3),
+ DEFINE_PREG(p4),
+ DEFINE_PREG(p5),
+ DEFINE_PREG(p6),
+ DEFINE_PREG(p7),
+ DEFINE_PREG(p8),
+ DEFINE_PREG(p9),
+ DEFINE_PREG(p10),
+ DEFINE_PREG(p11),
+ DEFINE_PREG(p12),
+ DEFINE_PREG(p13),
+ DEFINE_PREG(p14),
+ DEFINE_PREG(p15),
+
+ // DEFINE FFR
+ DEFINE_PREG(ffr)
+ // clang-format on
+};
+
+#endif // DECLARE_REGISTER_INFOS_ARM64_SVE_STRUCT
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h
index 343579cd2657..15c7cac544a1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h
@@ -87,15 +87,14 @@
nullptr, nullptr, nullptr, 0 \
}
-#define DEFINE_FP_MM(reg, i) \
+#define DEFINE_FP_MM(reg, i, streg) \
{ \
- #reg #i, nullptr, sizeof(uint64_t), \
- LLVM_EXTENSION FPR_OFFSET( \
- stmm[i]), eEncodingUint, eFormatHex, \
- {ehframe_mm##i##_i386, dwarf_mm##i##_i386, \
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
- lldb_mm##i##_i386 }, \
- nullptr, nullptr, nullptr, 0 \
+ #reg #i, nullptr, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
+ eEncodingUint, eFormatHex, \
+ {dwarf_mm##i##_i386, dwarf_mm##i##_i386, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, lldb_mm##i##_i386 }, \
+ RegisterContextPOSIX_x86::g_contained_##streg##_32, \
+ RegisterContextPOSIX_x86::g_invalidate_##streg##_32, nullptr, 0 \
}
#define DEFINE_XMM(reg, i) \
@@ -251,10 +250,12 @@ static RegisterInfo g_register_infos_i386[] = {
// 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),
+ DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7),
+
+ DEFINE_FP_MM(mm, 0, st0), DEFINE_FP_MM(mm, 1, st1),
+ DEFINE_FP_MM(mm, 2, st2), DEFINE_FP_MM(mm, 3, st3),
+ DEFINE_FP_MM(mm, 4, st4), DEFINE_FP_MM(mm, 5, st5),
+ DEFINE_FP_MM(mm, 6, st6), DEFINE_FP_MM(mm, 7, st7),
// XMM registers
DEFINE_XMM(xmm, 0), DEFINE_XMM(xmm, 1), DEFINE_XMM(xmm, 2),
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
index 51be31f8e028..90863dfdb090 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
@@ -10,8 +10,8 @@
// Computes the offset of the given GPR in the user data area.
#define GPR_OFFSET(regname) (offsetof(GPR, regname))
-#define FPR_OFFSET(regname) (offsetof(FPR, regname))
-#define VMX_OFFSET(regname) (offsetof(VMX, regname))
+#define FPR_OFFSET(regname) (sizeof(GPR) + offsetof(FPR, regname))
+#define VMX_OFFSET(regname) (sizeof(GPR) + sizeof(FPR) + offsetof(VMX, regname))
#define GPR_SIZE(regname) (sizeof(((GPR *)NULL)->regname))
#ifdef DECLARE_REGISTER_INFOS_POWERPC_STRUCT
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
index af3027afa73c..41c04b20f391 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
@@ -88,15 +88,14 @@
nullptr, nullptr, nullptr, 0 \
}
-#define DEFINE_FP_MM(reg, i) \
+#define DEFINE_FP_MM(reg, i, streg) \
{ \
- #reg #i, nullptr, 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 }, \
- nullptr, nullptr, nullptr, 0 \
+ #reg #i, nullptr, 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 }, \
+ RegisterContextPOSIX_x86::g_contained_##streg##_64, \
+ RegisterContextPOSIX_x86::g_invalidate_##streg##_64, nullptr, 0 \
}
#define DEFINE_XMM(reg, i) \
@@ -195,6 +194,14 @@
RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
}
+#define DEFINE_FPR_32(name, reg, kind1, kind2, kind3, kind4, reg64) \
+ { \
+ #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \
+ {kind1, kind2, kind3, kind4, lldb_##name##_x86_64 }, \
+ RegisterContextPOSIX_x86::g_contained_##reg64, \
+ RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \
+ }
+
// clang-format off
static RegisterInfo g_register_infos_x86_64[] = {
// General purpose registers EH_Frame DWARF Generic Process Plugin
@@ -251,26 +258,30 @@ static RegisterInfo g_register_infos_x86_64[] = {
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
-// ====================================== =============== ================== =================== ====================
+// i387 Floating point registers. EH_frame DWARF Generic Process Plugin reg64
+// ====================================== =============== ================== =================== ==================== =====
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_32(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fip),
+ DEFINE_FPR_32(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fip),
+ DEFINE_FPR(fip, ptr.x86_64.fip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_FPR_32(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fdp),
+ DEFINE_FPR_32(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fdp),
+ DEFINE_FPR(fdp, ptr.x86_64.fdp, 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),
+ DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7),
+
+ DEFINE_FP_MM(mm, 0, st0), DEFINE_FP_MM(mm, 1, st1),
+ DEFINE_FP_MM(mm, 2, st2), DEFINE_FP_MM(mm, 3, st3),
+ DEFINE_FP_MM(mm, 4, st4), DEFINE_FP_MM(mm, 5, st5),
+ DEFINE_FP_MM(mm, 6, st6), DEFINE_FP_MM(mm, 7, st7),
// XMM registers
DEFINE_XMM(xmm, 0), DEFINE_XMM(xmm, 1), DEFINE_XMM(xmm, 2),
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
index 35f1a4075d09..4d10600f4771 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h
@@ -106,7 +106,7 @@ enum {
lldb_bnd1_i386,
lldb_bnd2_i386,
lldb_bnd3_i386,
- k_last_mpxr = lldb_bnd3_i386,
+ k_last_mpxr_i386 = lldb_bnd3_i386,
k_first_mpxc_i386,
lldb_bndcfgu_i386 = k_first_mpxc_i386,
@@ -228,8 +228,10 @@ enum {
lldb_fop_x86_64,
lldb_fiseg_x86_64,
lldb_fioff_x86_64,
+ lldb_fip_x86_64,
lldb_foseg_x86_64,
lldb_fooff_x86_64,
+ lldb_fdp_x86_64,
lldb_mxcsr_x86_64,
lldb_mxcsrmask_x86_64,
lldb_st0_x86_64,
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index aa95e92607ad..ae19367ca3ae 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -52,9 +52,10 @@ void ProcessElfCore::Terminate() {
lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp,
lldb::ListenerSP listener_sp,
- const FileSpec *crash_file) {
+ const FileSpec *crash_file,
+ bool can_connect) {
lldb::ProcessSP process_sp;
- if (crash_file) {
+ if (crash_file && !can_connect) {
// Read enough data for a ELF32 header or ELF64 header Note: Here we care
// about e_type field only, so it is safe to ignore possible presence of
// the header extension.
@@ -97,7 +98,7 @@ bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp,
ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp,
lldb::ListenerSP listener_sp,
const FileSpec &core_file)
- : Process(target_sp, listener_sp), m_core_file(core_file) {}
+ : PostMortemProcess(target_sp, listener_sp), m_core_file(core_file) {}
// Destructor
ProcessElfCore::~ProcessElfCore() {
@@ -260,8 +261,8 @@ lldb_private::DynamicLoader *ProcessElfCore::GetDynamicLoader() {
return m_dyld_up.get();
}
-bool ProcessElfCore::UpdateThreadList(ThreadList &old_thread_list,
- ThreadList &new_thread_list) {
+bool ProcessElfCore::DoUpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
const uint32_t num_threads = GetNumThreadContexts();
if (!m_thread_data_valid)
return false;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
index 6f6309799f43..d8e3cc9ae3e1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -19,7 +19,7 @@
#include <list>
#include <vector>
-#include "lldb/Target/Process.h"
+#include "lldb/Target/PostMortemProcess.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
@@ -28,12 +28,13 @@
struct ThreadData;
-class ProcessElfCore : public lldb_private::Process {
+class ProcessElfCore : public lldb_private::PostMortemProcess {
public:
// Constructors and Destructors
static lldb::ProcessSP
CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec *crash_file_path);
+ const lldb_private::FileSpec *crash_file_path,
+ bool can_connect);
static void Initialize();
@@ -104,8 +105,8 @@ public:
protected:
void Clear();
- bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
- lldb_private::ThreadList &new_thread_list) override;
+ bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list,
+ lldb_private::ThreadList &new_thread_list) override;
private:
struct NT_FILE_Entry {
@@ -125,8 +126,6 @@ private:
lldb::ModuleSP m_core_module_sp;
lldb_private::FileSpec m_core_file;
std::string m_dyld_plugin_name;
- ProcessElfCore(const ProcessElfCore &) = delete;
- const ProcessElfCore &operator=(const ProcessElfCore &) = delete;
// True if m_thread_contexts contains valid entries
bool m_thread_data_valid = false;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
index b76f26a584c0..2f71f175a00d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
@@ -16,9 +16,9 @@
using namespace lldb_private;
RegisterContextCorePOSIX_arm::RegisterContextCorePOSIX_arm(
- Thread &thread, RegisterInfoInterface *register_info,
+ Thread &thread, std::unique_ptr<RegisterInfoPOSIX_arm> register_info,
const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
- : RegisterContextPOSIX_arm(thread, 0, register_info) {
+ : RegisterContextPOSIX_arm(thread, std::move(register_info)) {
m_gpr_buffer = std::make_shared<DataBufferHeap>(gpregset.GetDataStart(),
gpregset.GetByteSize());
m_gpr.SetData(m_gpr_buffer);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
index f9ec08ed35fc..de343f9001e0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
@@ -18,7 +18,7 @@ class RegisterContextCorePOSIX_arm : public RegisterContextPOSIX_arm {
public:
RegisterContextCorePOSIX_arm(
lldb_private::Thread &thread,
- lldb_private::RegisterInfoInterface *register_info,
+ std::unique_ptr<RegisterInfoPOSIX_arm> register_info,
const lldb_private::DataExtractor &gpregset,
llvm::ArrayRef<lldb_private::CoreNote> notes);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index 685567416983..129a887a550c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "RegisterContextPOSIXCore_arm64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Target/Thread.h"
@@ -27,6 +28,12 @@ RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
m_fpregset = getRegset(
notes, m_register_info_up->GetTargetArchitecture().GetTriple(), FPR_Desc);
+
+ m_sveregset =
+ getRegset(notes, m_register_info_up->GetTargetArchitecture().GetTriple(),
+ AARCH64_SVE_Desc);
+
+ ConfigureRegisterContext();
}
RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64() {}
@@ -45,9 +52,57 @@ bool RegisterContextCorePOSIX_arm64::WriteFPR() {
return false;
}
+const uint8_t *RegisterContextCorePOSIX_arm64::GetSVEBuffer(uint64_t offset) {
+ return m_sveregset.GetDataStart() + offset;
+}
+
+void RegisterContextCorePOSIX_arm64::ConfigureRegisterContext() {
+ if (m_sveregset.GetByteSize() > sizeof(sve::user_sve_header)) {
+ uint64_t sve_header_field_offset = 8;
+ m_sve_vector_length = m_sveregset.GetU16(&sve_header_field_offset);
+ sve_header_field_offset = 12;
+ uint16_t sve_header_flags_field =
+ m_sveregset.GetU16(&sve_header_field_offset);
+ if ((sve_header_flags_field & sve::ptrace_regs_mask) ==
+ sve::ptrace_regs_fpsimd)
+ m_sve_state = SVEState::FPSIMD;
+ else if ((sve_header_flags_field & sve::ptrace_regs_mask) ==
+ sve::ptrace_regs_sve)
+ m_sve_state = SVEState::Full;
+
+ if (sve::vl_valid(m_sve_vector_length))
+ m_register_info_up->ConfigureVectorRegisterInfos(
+ sve::vq_from_vl(m_sve_vector_length));
+ else {
+ m_sve_state = SVEState::Disabled;
+ m_sve_vector_length = 0;
+ }
+ } else
+ m_sve_state = SVEState::Disabled;
+}
+
+uint32_t RegisterContextCorePOSIX_arm64::CalculateSVEOffset(
+ const RegisterInfo *reg_info) {
+ // Start of Z0 data is after GPRs plus 8 bytes of vg register
+ uint32_t sve_reg_offset = LLDB_INVALID_INDEX32;
+ if (m_sve_state == SVEState::FPSIMD) {
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ sve_reg_offset = sve::ptrace_fpsimd_offset + (reg - GetRegNumSVEZ0()) * 16;
+ } else if (m_sve_state == SVEState::Full) {
+ uint32_t sve_z0_offset = GetGPRSize() + 16;
+ sve_reg_offset =
+ sve::SigRegsOffset() + reg_info->byte_offset - sve_z0_offset;
+ }
+
+ return sve_reg_offset;
+}
+
bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
RegisterValue &value) {
- lldb::offset_t offset = reg_info->byte_offset;
+ Status error;
+ lldb::offset_t offset;
+
+ offset = reg_info->byte_offset;
if (offset + reg_info->byte_size <= GetGPRSize()) {
uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
if (offset == reg_info->byte_offset + reg_info->byte_size) {
@@ -60,15 +115,86 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
if (reg == LLDB_INVALID_REGNUM)
return false;
- offset -= GetGPRSize();
- if (IsFPR(reg) && offset + reg_info->byte_size <= GetFPUSize()) {
- Status error;
- value.SetFromMemoryData(reg_info, m_fpregset.GetDataStart() + offset,
- reg_info->byte_size, lldb::eByteOrderLittle, error);
- return error.Success();
- }
+ if (IsFPR(reg)) {
+ if (m_sve_state == SVEState::Disabled) {
+ // SVE is disabled take legacy route for FPU register access
+ offset -= GetGPRSize();
+ if (offset < m_fpregset.GetByteSize()) {
+ value.SetFromMemoryData(reg_info, m_fpregset.GetDataStart() + offset,
+ reg_info->byte_size, lldb::eByteOrderLittle,
+ error);
+ return error.Success();
+ }
+ } else {
+ // FPSR and FPCR will be located right after Z registers in
+ // SVEState::FPSIMD while in SVEState::Full they will be located at the
+ // end of register data after an alignment correction based on currently
+ // selected vector length.
+ uint32_t sve_reg_num = LLDB_INVALID_REGNUM;
+ if (reg == GetRegNumFPSR()) {
+ sve_reg_num = reg;
+ if (m_sve_state == SVEState::Full)
+ offset = sve::PTraceFPSROffset(sve::vq_from_vl(m_sve_vector_length));
+ else if (m_sve_state == SVEState::FPSIMD)
+ offset = sve::ptrace_fpsimd_offset + (32 * 16);
+ } else if (reg == GetRegNumFPCR()) {
+ sve_reg_num = reg;
+ if (m_sve_state == SVEState::Full)
+ offset = sve::PTraceFPCROffset(sve::vq_from_vl(m_sve_vector_length));
+ else if (m_sve_state == SVEState::FPSIMD)
+ offset = sve::ptrace_fpsimd_offset + (32 * 16) + 4;
+ } else {
+ // Extract SVE Z register value register number for this reg_info
+ if (reg_info->value_regs &&
+ reg_info->value_regs[0] != LLDB_INVALID_REGNUM)
+ sve_reg_num = reg_info->value_regs[0];
+ offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
+ }
+
+ assert(sve_reg_num != LLDB_INVALID_REGNUM);
+ assert(offset < m_sveregset.GetByteSize());
+ value.SetFromMemoryData(reg_info, GetSVEBuffer(offset),
+ reg_info->byte_size, lldb::eByteOrderLittle,
+ error);
+ }
+ } else if (IsSVE(reg)) {
+ if (IsSVEVG(reg)) {
+ value = GetSVERegVG();
+ return true;
+ }
- return false;
+ switch (m_sve_state) {
+ case SVEState::FPSIMD: {
+ // In FPSIMD state SVE payload mirrors legacy fpsimd struct and so just
+ // copy 16 bytes of v register to the start of z register. All other
+ // SVE register will be set to zero.
+ uint64_t byte_size = 1;
+ uint8_t zeros = 0;
+ const uint8_t *src = &zeros;
+ if (IsSVEZ(reg)) {
+ byte_size = 16;
+ offset = CalculateSVEOffset(reg_info);
+ assert(offset < m_sveregset.GetByteSize());
+ src = GetSVEBuffer(offset);
+ }
+ value.SetFromMemoryData(reg_info, src, byte_size, lldb::eByteOrderLittle,
+ error);
+ } break;
+ case SVEState::Full:
+ offset = CalculateSVEOffset(reg_info);
+ assert(offset < m_sveregset.GetByteSize());
+ value.SetFromMemoryData(reg_info, GetSVEBuffer(offset),
+ reg_info->byte_size, lldb::eByteOrderLittle,
+ error);
+ break;
+ case SVEState::Disabled:
+ default:
+ return false;
+ }
+ } else
+ return false;
+
+ return error.Success();
}
bool RegisterContextCorePOSIX_arm64::ReadAllRegisterValues(
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
index 830e0ff91e4c..a4fdc4f14328 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
@@ -9,7 +9,9 @@
#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM64_H
#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM64_H
+#include "Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
+
#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
@@ -49,6 +51,18 @@ private:
lldb::DataBufferSP m_gpr_buffer;
lldb_private::DataExtractor m_gpr;
lldb_private::DataExtractor m_fpregset;
+ lldb_private::DataExtractor m_sveregset;
+
+ SVEState m_sve_state;
+ uint16_t m_sve_vector_length = 0;
+
+ const uint8_t *GetSVEBuffer(uint64_t offset = 0);
+
+ void ConfigureRegisterContext();
+
+ uint32_t CalculateSVEOffset(const lldb_private::RegisterInfo *reg_info);
+
+ uint64_t GetSVERegVG() { return m_sve_vector_length / 8; }
};
#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM64_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
index 4e08aa280817..25abd7ed54b7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
@@ -107,6 +107,10 @@ constexpr RegsetDesc FPR_Desc[] = {
{llvm::Triple::OpenBSD, llvm::Triple::UnknownArch, OPENBSD::NT_FPREGS},
};
+constexpr RegsetDesc AARCH64_SVE_Desc[] = {
+ {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_SVE},
+};
+
constexpr RegsetDesc PPC_VMX_Desc[] = {
{llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
{llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index 9083ee060f07..6c3ee9debc7c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -86,9 +86,7 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
case llvm::Triple::FreeBSD: {
switch (arch.GetMachine()) {
case llvm::Triple::aarch64:
- break;
case llvm::Triple::arm:
- reg_interface = new RegisterInfoPOSIX_arm(arch);
break;
case llvm::Triple::ppc:
reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
@@ -126,9 +124,6 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
case llvm::Triple::Linux: {
switch (arch.GetMachine()) {
- case llvm::Triple::arm:
- reg_interface = new RegisterInfoPOSIX_arm(arch);
- break;
case llvm::Triple::aarch64:
break;
case llvm::Triple::mipsel:
@@ -163,9 +158,6 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
switch (arch.GetMachine()) {
case llvm::Triple::aarch64:
break;
- case llvm::Triple::arm:
- reg_interface = new RegisterInfoPOSIX_arm(arch);
- break;
case llvm::Triple::x86:
reg_interface = new RegisterContextOpenBSD_i386(arch);
break;
@@ -182,7 +174,8 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
break;
}
- if (!reg_interface && arch.GetMachine() != llvm::Triple::aarch64) {
+ if (!reg_interface && arch.GetMachine() != llvm::Triple::aarch64 &&
+ arch.GetMachine() != llvm::Triple::arm) {
LLDB_LOGF(log, "elf-core::%s:: Architecture(%d) or OS(%d) not supported",
__FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
assert(false && "Architecture or OS not supported");
@@ -196,7 +189,8 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
break;
case llvm::Triple::arm:
m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm>(
- *this, reg_interface, m_gpregset_data, m_notes);
+ *this, std::make_unique<RegisterInfoPOSIX_arm>(arch), m_gpregset_data,
+ m_notes);
break;
case llvm::Triple::mipsel:
case llvm::Triple::mips:
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index bfacd41dc1a3..4981345d6a18 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -50,7 +50,7 @@
#include <compression.h>
#endif
-#if defined(HAVE_LIBZ)
+#if LLVM_ENABLE_ZLIB
#include <zlib.h>
#endif
@@ -284,7 +284,7 @@ GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet,
LLDB_LOGV(log,
"Read(buffer, sizeof(buffer), timeout = {0}, "
"status = {1}, error = {2}) => bytes_read = {3}",
- timeout, Communication::ConnectionStatusAsCString(status), error,
+ timeout, Communication::ConnectionStatusAsString(status), error,
bytes_read);
if (bytes_read > 0) {
@@ -582,7 +582,7 @@ bool GDBRemoteCommunication::DecompressPacket() {
}
#endif
-#if defined(HAVE_LIBZ)
+#if LLVM_ENABLE_ZLIB
if (decompressed_bytes == 0 && decompressed_bufsize != ULONG_MAX &&
decompressed_buffer != nullptr &&
m_compression_type == CompressionType::ZlibDeflate) {
@@ -1234,7 +1234,7 @@ GDBRemoteCommunication::ConnectLocally(GDBRemoteCommunication &client,
const int backlog = 5;
TCPSocket listen_socket(true, child_processes_inherit);
if (llvm::Error error =
- listen_socket.Listen("127.0.0.1:0", backlog).ToError())
+ listen_socket.Listen("localhost:0", backlog).ToError())
return error;
Socket *accept_socket;
@@ -1243,7 +1243,7 @@ GDBRemoteCommunication::ConnectLocally(GDBRemoteCommunication &client,
llvm::SmallString<32> remote_addr;
llvm::raw_svector_ostream(remote_addr)
- << "connect://127.0.0.1:" << listen_socket.GetLocalPortNumber();
+ << "connect://localhost:" << listen_socket.GetLocalPortNumber();
std::unique_ptr<ConnectionFileDescriptor> conn_up(
new ConnectionFileDescriptor());
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index c75d5e106cd0..d375a312ae2c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1053,7 +1053,7 @@ void GDBRemoteCommunicationClient::MaybeEnableCompression(
}
#endif
-#if defined(HAVE_LIBZ)
+#if LLVM_ENABLE_ZLIB
if (avail_type == CompressionType::None) {
for (auto compression : supported_compressions) {
if (compression == "zlib-deflate") {
@@ -1529,6 +1529,22 @@ Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
std::string name;
name_extractor.GetHexByteString(name);
region_info.SetName(name.c_str());
+ } else if (name.equals("flags")) {
+ region_info.SetMemoryTagged(MemoryRegionInfo::eNo);
+
+ llvm::StringRef flags = value;
+ llvm::StringRef flag;
+ while (flags.size()) {
+ flags = flags.ltrim();
+ std::tie(flag, flags) = flags.split(' ');
+ // To account for trailing whitespace
+ if (flag.size()) {
+ if (flag == "mt") {
+ region_info.SetMemoryTagged(MemoryRegionInfo::eYes);
+ break;
+ }
+ }
+ }
} else if (name.equals("error")) {
StringExtractorGDBRemote error_extractor(value);
std::string error_string;
@@ -1701,14 +1717,9 @@ Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) {
// Set num to 0 first.
num = 0;
if (m_supports_watchpoint_support_info != eLazyBoolNo) {
- char packet[64];
- const int packet_len =
- ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
- assert(packet_len < (int)sizeof(packet));
- UNUSED_IF_ASSERT_DISABLED(packet_len);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, response, false) ==
- PacketResult::Success) {
+ if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response,
+ false) == PacketResult::Success) {
m_supports_watchpoint_support_info = eLazyBoolYes;
llvm::StringRef name;
llvm::StringRef value;
@@ -2120,6 +2131,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
case llvm::Triple::COFF:
m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub);
break;
+ case llvm::Triple::GOFF:
case llvm::Triple::Wasm:
case llvm::Triple::XCOFF:
LLDB_LOGF(log, "error: not supported target architecture");
@@ -2816,7 +2828,7 @@ lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {
}
lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand(
- const char *command, // Shouldn't be NULL
+ llvm::StringRef command,
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
@@ -2827,7 +2839,7 @@ lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand(
const Timeout<std::micro> &timeout) {
lldb_private::StreamString stream;
stream.PutCString("qPlatform_shell:");
- stream.PutBytesAsRawHex8(command, strlen(command));
+ stream.PutBytesAsRawHex8(command.data(), command.size());
stream.PutChar(',');
uint32_t timeout_sec = UINT32_MAX;
if (timeout) {
@@ -2981,6 +2993,31 @@ lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize(
return UINT64_MAX;
}
+void GDBRemoteCommunicationClient::AutoCompleteDiskFileOrDirectory(
+ CompletionRequest &request, bool only_dir) {
+ lldb_private::StreamString stream;
+ stream.PutCString("qPathComplete:");
+ stream.PutHex32(only_dir ? 1 : 0);
+ stream.PutChar(',');
+ stream.PutStringAsRawHex8(request.GetCursorArgumentPrefix());
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+ PacketResult::Success) {
+ StreamString strm;
+ char ch = response.GetChar();
+ if (ch != 'M')
+ return;
+ while (response.Peek()) {
+ strm.Clear();
+ while ((ch = response.GetHexU8(0, false)) != '\0')
+ strm.PutChar(ch);
+ request.AddCompletion(strm.GetString());
+ if (response.GetChar() != ',')
+ break;
+ }
+ }
+}
+
Status
GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
uint32_t &file_permissions) {
@@ -3433,6 +3470,35 @@ Status GDBRemoteCommunicationClient::SendGetMetaDataPacket(
return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
}
+llvm::Expected<TraceTypeInfo>
+GDBRemoteCommunicationClient::SendGetSupportedTraceType() {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+
+ StreamGDBRemote escaped_packet;
+ escaped_packet.PutCString("jLLDBTraceSupportedType");
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
+ true) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ if (response.IsErrorResponse())
+ return response.GetStatus().ToError();
+ if (response.IsUnsupportedResponse())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "jLLDBTraceSupportedType is unsupported");
+
+ if (llvm::Expected<TraceTypeInfo> type =
+ llvm::json::parse<TraceTypeInfo>(response.Peek()))
+ return *type;
+ else
+ return type.takeError();
+ }
+ LLDB_LOG(log, "failed to send packet: jLLDBTraceSupportedType");
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "failed to send packet: jLLDBTraceSupportedType");
+}
+
Status
GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid,
TraceOptions &options) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 8df08cbde735..af3755fce774 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -22,6 +22,7 @@
#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/ProcessInfo.h"
#include "lldb/Utility/StructuredData.h"
+#include "lldb/Utility/TraceOptions.h"
#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h"
#endif
@@ -375,6 +376,9 @@ public:
lldb::user_id_t GetFileSize(const FileSpec &file_spec);
+ void AutoCompleteDiskFileOrDirectory(CompletionRequest &request,
+ bool only_dir);
+
Status GetFilePermissions(const FileSpec &file_spec,
uint32_t &file_permissions);
@@ -396,7 +400,7 @@ public:
bool GetFileExists(const FileSpec &file_spec);
Status RunShellCommand(
- const char *command, // Shouldn't be nullptr
+ llvm::StringRef command,
const FileSpec &working_dir, // Pass empty FileSpec to use the current
// working directory
int *status_ptr, // Pass nullptr if you don't want the process exit status
@@ -516,6 +520,8 @@ public:
Status SendGetTraceConfigPacket(lldb::user_id_t uid, TraceOptions &options);
+ llvm::Expected<TraceTypeInfo> SendGetSupportedTraceType();
+
protected:
LazyBool m_supports_not_sending_acks;
LazyBool m_supports_thread_suffix;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index b78f0916b9b9..60548efc0f33 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -12,11 +12,11 @@
#include "GDBRemoteCommunicationServer.h"
-#include <cstring>
-
#include "ProcessGDBRemoteLog.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"
+#include "lldb/Utility/UnimplementedError.h"
+#include <cstring>
using namespace lldb;
using namespace lldb_private;
@@ -113,18 +113,17 @@ GDBRemoteCommunicationServer::SendErrorResponse(const Status &error) {
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendErrorResponse(llvm::Error error) {
+ assert(error);
std::unique_ptr<llvm::ErrorInfoBase> EIB;
- std::unique_ptr<PacketUnimplementedError> PUE;
+ std::unique_ptr<UnimplementedError> UE;
llvm::handleAllErrors(
std::move(error),
- [&](std::unique_ptr<PacketUnimplementedError> E) { PUE = std::move(E); },
+ [&](std::unique_ptr<UnimplementedError> E) { UE = std::move(E); },
[&](std::unique_ptr<llvm::ErrorInfoBase> E) { EIB = std::move(E); });
if (EIB)
return SendErrorResponse(Status(llvm::Error(std::move(EIB))));
- if (PUE)
- return SendUnimplementedResponse(PUE->message().c_str());
- return SendErrorResponse(Status("Unknown Error"));
+ return SendUnimplementedResponse("");
}
GDBRemoteCommunication::PacketResult
@@ -152,5 +151,3 @@ GDBRemoteCommunicationServer::SendOKResponse() {
bool GDBRemoteCommunicationServer::HandshakeWithClient() {
return GetAck() == PacketResult::Success;
}
-
-char PacketUnimplementedError::ID;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index a7c2ea47e3ba..a1cf70f9cd1a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -27,7 +27,6 @@ class ProcessGDBRemote;
class GDBRemoteCommunicationServer : public GDBRemoteCommunication {
public:
- using PortMap = std::map<uint16_t, lldb::pid_t>;
using PacketHandler =
std::function<PacketResult(StringExtractorGDBRemote &packet,
Status &error, bool &interrupt, bool &quit)>;
@@ -79,18 +78,6 @@ private:
operator=(const GDBRemoteCommunicationServer &) = delete;
};
-class PacketUnimplementedError
- : public llvm::ErrorInfo<PacketUnimplementedError, llvm::StringError> {
-public:
- static char ID;
- using llvm::ErrorInfo<PacketUnimplementedError,
- llvm::StringError>::ErrorInfo; // inherit constructors
- PacketUnimplementedError(const llvm::Twine &S)
- : ErrorInfo(S, llvm::errc::not_supported) {}
-
- PacketUnimplementedError() : ErrorInfo(llvm::errc::not_supported) {}
-};
-
} // namespace process_gdb_remote
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index 08d489851799..1ca0290eda13 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -843,7 +843,7 @@ GDBRemoteCommunicationServerCommon::Handle_qSupported(
response.PutCString(";QListThreadsInStopReply+");
response.PutCString(";qEcho+");
response.PutCString(";qXfer:features:read+");
-#if defined(__linux__) || defined(__NetBSD__)
+#if defined(__linux__) || defined(__NetBSD__) || defined(__FreeBSD__)
response.PutCString(";QPassSignals+");
response.PutCString(";qXfer:auxv:read+");
response.PutCString(";qXfer:libraries-svr4:read+");
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index ae2f4bd041c9..62a09a2a432c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -10,13 +10,12 @@
#include "lldb/Host/Config.h"
-#include "GDBRemoteCommunicationServerLLGS.h"
-#include "lldb/Utility/GDBRemote.h"
#include <chrono>
#include <cstring>
#include <thread>
+#include "GDBRemoteCommunicationServerLLGS.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Debug.h"
#include "lldb/Host/File.h"
@@ -32,11 +31,13 @@
#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/UnimplementedError.h"
#include "lldb/Utility/UriParser.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/JSON.h"
@@ -92,6 +93,10 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
&GDBRemoteCommunicationServerLLGS::Handle_memory_read);
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_M,
&GDBRemoteCommunicationServerLLGS::Handle_M);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType__M,
+ &GDBRemoteCommunicationServerLLGS::Handle__M);
+ RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType__m,
+ &GDBRemoteCommunicationServerLLGS::Handle__m);
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_p,
&GDBRemoteCommunicationServerLLGS::Handle_p);
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_P,
@@ -155,6 +160,15 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
StringExtractorGDBRemote::eServerPacketType_vAttach,
&GDBRemoteCommunicationServerLLGS::Handle_vAttach);
RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vAttachWait,
+ &GDBRemoteCommunicationServerLLGS::Handle_vAttachWait);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qVAttachOrWaitSupported,
+ &GDBRemoteCommunicationServerLLGS::Handle_qVAttachOrWaitSupported);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vAttachOrWait,
+ &GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait);
+ RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_vCont,
&GDBRemoteCommunicationServerLLGS::Handle_vCont);
RegisterMemberFunctionHandler(
@@ -186,6 +200,9 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_jTraceConfigRead,
&GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_jLLDBTraceSupportedType,
+ &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupportedType);
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_g,
&GDBRemoteCommunicationServerLLGS::Handle_g);
@@ -326,6 +343,75 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
return Status();
}
+Status GDBRemoteCommunicationServerLLGS::AttachWaitProcess(
+ llvm::StringRef process_name, bool include_existing) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ std::chrono::milliseconds polling_interval = std::chrono::milliseconds(1);
+
+ // Create the matcher used to search the process list.
+ ProcessInstanceInfoList exclusion_list;
+ ProcessInstanceInfoMatch match_info;
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(
+ process_name, llvm::sys::path::Style::native);
+ match_info.SetNameMatchType(NameMatch::Equals);
+
+ if (include_existing) {
+ LLDB_LOG(log, "including existing processes in search");
+ } else {
+ // Create the excluded process list before polling begins.
+ Host::FindProcesses(match_info, exclusion_list);
+ LLDB_LOG(log, "placed '{0}' processes in the exclusion list.",
+ exclusion_list.size());
+ }
+
+ LLDB_LOG(log, "waiting for '{0}' to appear", process_name);
+
+ auto is_in_exclusion_list =
+ [&exclusion_list](const ProcessInstanceInfo &info) {
+ for (auto &excluded : exclusion_list) {
+ if (excluded.GetProcessID() == info.GetProcessID())
+ return true;
+ }
+ return false;
+ };
+
+ ProcessInstanceInfoList loop_process_list;
+ while (true) {
+ loop_process_list.clear();
+ if (Host::FindProcesses(match_info, loop_process_list)) {
+ // Remove all the elements that are in the exclusion list.
+ llvm::erase_if(loop_process_list, is_in_exclusion_list);
+
+ // One match! We found the desired process.
+ if (loop_process_list.size() == 1) {
+ auto matching_process_pid = loop_process_list[0].GetProcessID();
+ LLDB_LOG(log, "found pid {0}", matching_process_pid);
+ return AttachToProcess(matching_process_pid);
+ }
+
+ // Multiple matches! Return an error reporting the PIDs we found.
+ if (loop_process_list.size() > 1) {
+ StreamString error_stream;
+ error_stream.Format(
+ "Multiple executables with name: '{0}' found. Pids: ",
+ process_name);
+ for (size_t i = 0; i < loop_process_list.size() - 1; ++i) {
+ error_stream.Format("{0}, ", loop_process_list[i].GetProcessID());
+ }
+ error_stream.Format("{0}.", loop_process_list.back().GetProcessID());
+
+ Status error;
+ error.SetErrorString(error_stream.GetString());
+ return error;
+ }
+ }
+ // No matches, we have not found the process. Sleep until next poll.
+ LLDB_LOG(log, "sleep {0} seconds", polling_interval);
+ std::this_thread::sleep_for(polling_interval);
+ }
+}
+
void GDBRemoteCommunicationServerLLGS::InitializeDelegate(
NativeProcessProtocol *process) {
assert(process && "process cannot be NULL");
@@ -495,7 +581,7 @@ static void WriteRegisterValueInHexFixedWidth(
}
}
-static llvm::Expected<json::Object>
+static llvm::Optional<json::Object>
GetRegistersAsJSON(NativeThreadProtocol &thread) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
@@ -504,30 +590,16 @@ GetRegistersAsJSON(NativeThreadProtocol &thread) {
json::Object register_object;
#ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET
- // Expedite all registers in the first register set (i.e. should be GPRs)
- // that are not contained in other registers.
- const RegisterSet *reg_set_p = reg_ctx_sp->GetRegisterSet(0);
- if (!reg_set_p)
- return llvm::make_error<llvm::StringError>("failed to get registers",
- llvm::inconvertibleErrorCode());
- for (const uint32_t *reg_num_p = reg_set_p->registers;
- *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
- uint32_t reg_num = *reg_num_p;
+ const auto expedited_regs =
+ reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Full);
#else
- // Expedite only a couple of registers until we figure out why sending
- // registers is expensive.
- static const uint32_t k_expedited_registers[] = {
- LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_SP, LLDB_REGNUM_GENERIC_FP,
- LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM};
-
- for (const uint32_t *generic_reg_p = k_expedited_registers;
- *generic_reg_p != LLDB_INVALID_REGNUM; ++generic_reg_p) {
- uint32_t reg_num = reg_ctx.ConvertRegisterKindToRegisterNumber(
- eRegisterKindGeneric, *generic_reg_p);
- if (reg_num == LLDB_INVALID_REGNUM)
- continue; // Target does not support the given register.
+ const auto expedited_regs =
+ reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Minimal);
#endif
+ if (expedited_regs.empty())
+ return llvm::None;
+ for (auto &reg_num : expedited_regs) {
const RegisterInfo *const reg_info_p =
reg_ctx.GetRegisterInfoAtIndex(reg_num);
if (reg_info_p == nullptr) {
@@ -620,12 +692,8 @@ GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) {
json::Object thread_obj;
if (!abridged) {
- if (llvm::Expected<json::Object> registers =
- GetRegistersAsJSON(*thread)) {
+ if (llvm::Optional<json::Object> registers = GetRegistersAsJSON(*thread))
thread_obj.try_emplace("registers", std::move(*registers));
- } else {
- return registers.takeError();
- }
}
thread_obj.try_emplace("tid", static_cast<int64_t>(tid));
@@ -806,46 +874,27 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
// Grab the register context.
NativeRegisterContext& reg_ctx = thread->GetRegisterContext();
- // Expedite all registers in the first register set (i.e. should be GPRs)
- // that are not contained in other registers.
- const RegisterSet *reg_set_p;
- if (reg_ctx.GetRegisterSetCount() > 0 &&
- ((reg_set_p = reg_ctx.GetRegisterSet(0)) != nullptr)) {
- LLDB_LOGF(log,
- "GDBRemoteCommunicationServerLLGS::%s expediting registers "
- "from set '%s' (registers set count: %zu)",
- __FUNCTION__, reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
- reg_set_p->num_registers);
+ const auto expedited_regs =
+ reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Full);
- for (const uint32_t *reg_num_p = reg_set_p->registers;
- *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
- const RegisterInfo *const reg_info_p =
- reg_ctx.GetRegisterInfoAtIndex(*reg_num_p);
- if (reg_info_p == nullptr) {
- LLDB_LOGF(log,
- "GDBRemoteCommunicationServerLLGS::%s failed to get "
- "register info for register set '%s', register index "
- "%" PRIu32,
+ for (auto &reg_num : expedited_regs) {
+ const RegisterInfo *const reg_info_p =
+ reg_ctx.GetRegisterInfoAtIndex(reg_num);
+ // Only expediate registers that are not contained in other registers.
+ if (reg_info_p != nullptr && reg_info_p->value_regs == nullptr) {
+ RegisterValue reg_value;
+ Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
+ if (error.Success()) {
+ response.Printf("%.02x:", reg_num);
+ WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p,
+ &reg_value, lldb::eByteOrderBig);
+ response.PutChar(';');
+ } else {
+ LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s failed to read "
+ "register '%s' index %" PRIu32 ": %s",
__FUNCTION__,
- reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
- *reg_num_p);
- } else if (reg_info_p->value_regs == nullptr) {
- // Only expediate registers that are not contained in other registers.
- RegisterValue reg_value;
- Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
- if (error.Success()) {
- response.Printf("%.02x:", *reg_num_p);
- WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p,
- &reg_value, lldb::eByteOrderBig);
- response.PutChar(';');
- } else {
- LLDB_LOGF(log,
- "GDBRemoteCommunicationServerLLGS::%s failed to read "
- "register '%s' index %" PRIu32 ": %s",
- __FUNCTION__,
- reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
- *reg_num_p, error.AsCString());
- }
+ reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
+ reg_num, error.AsCString());
}
}
}
@@ -1222,6 +1271,33 @@ GDBRemoteCommunicationServerLLGS::Handle_jTraceStop(
}
GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupportedType(
+ StringExtractorGDBRemote &packet) {
+
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_up ||
+ (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(Status("Process not running."));
+
+ llvm::Expected<TraceTypeInfo> supported_trace_type =
+ m_debugged_process_up->GetSupportedTraceType();
+ if (!supported_trace_type)
+ return SendErrorResponse(supported_trace_type.takeError());
+
+ StreamGDBRemote escaped_response;
+ StructuredData::Dictionary json_packet;
+
+ json_packet.AddStringItem("name", supported_trace_type->name);
+ json_packet.AddStringItem("description", supported_trace_type->description);
+
+ StreamString json_string;
+ json_packet.Dump(json_string, false);
+ escaped_response.PutEscapedBytes(json_string.GetData(),
+ json_string.GetSize());
+ return SendPacketNoLock(escaped_response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead(
StringExtractorGDBRemote &packet) {
@@ -1723,6 +1799,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReasonForState(
case eStateSuspended:
case eStateStopped:
case eStateCrashed: {
+ assert(m_debugged_process_up != nullptr);
lldb::tid_t tid = m_debugged_process_up->GetCurrentThreadID();
// Make sure we set the current thread so g and p packets return the data
// the gdb will expect.
@@ -1789,8 +1866,10 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
response.PutChar(';');
}
- response.Printf("bitsize:%" PRIu32 ";offset:%" PRIu32 ";",
- reg_info->byte_size * 8, reg_info->byte_offset);
+ response.Printf("bitsize:%" PRIu32 ";", reg_info->byte_size * 8);
+
+ if (!reg_context.RegisterOffsetIsDynamic())
+ response.Printf("offset:%" PRIu32 ";", reg_info->byte_offset);
llvm::StringRef encoding = GetEncodingNameOrEmpty(*reg_info);
if (!encoding.empty())
@@ -2085,7 +2164,7 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
StreamGDBRemote response;
RegisterValue reg_value(
- reg_bytes, reg_size,
+ makeArrayRef(reg_bytes, reg_size),
m_debugged_process_up->GetArchitecture().GetByteOrder());
Status error = reg_context.WriteRegister(reg_info, reg_value);
if (error.Fail()) {
@@ -2321,6 +2400,84 @@ GDBRemoteCommunicationServerLLGS::Handle_memory_read(
}
GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle__M(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (!m_debugged_process_up ||
+ (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Parse out the memory address.
+ packet.SetFilePos(strlen("_M"));
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Too short _M packet");
+
+ const lldb::addr_t size = packet.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
+ if (size == LLDB_INVALID_ADDRESS)
+ return SendIllFormedResponse(packet, "Address not valid");
+ if (packet.GetChar() != ',')
+ return SendIllFormedResponse(packet, "Bad packet");
+ Permissions perms = {};
+ while (packet.GetBytesLeft() > 0) {
+ switch (packet.GetChar()) {
+ case 'r':
+ perms |= ePermissionsReadable;
+ break;
+ case 'w':
+ perms |= ePermissionsWritable;
+ break;
+ case 'x':
+ perms |= ePermissionsExecutable;
+ break;
+ default:
+ return SendIllFormedResponse(packet, "Bad permissions");
+ }
+ }
+
+ llvm::Expected<addr_t> addr =
+ m_debugged_process_up->AllocateMemory(size, perms);
+ if (!addr)
+ return SendErrorResponse(addr.takeError());
+
+ StreamGDBRemote response;
+ response.PutHex64(*addr);
+ return SendPacketNoLock(response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle__m(StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ if (!m_debugged_process_up ||
+ (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ LLDB_LOGF(
+ log,
+ "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+ __FUNCTION__);
+ return SendErrorResponse(0x15);
+ }
+
+ // Parse out the memory address.
+ packet.SetFilePos(strlen("_m"));
+ if (packet.GetBytesLeft() < 1)
+ return SendIllFormedResponse(packet, "Too short m packet");
+
+ const lldb::addr_t addr = packet.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
+ if (addr == LLDB_INVALID_ADDRESS)
+ return SendIllFormedResponse(packet, "Address not valid");
+
+ if (llvm::Error Err = m_debugged_process_up->DeallocateMemory(addr))
+ return SendErrorResponse(std::move(Err));
+
+ return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
@@ -2491,6 +2648,17 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo(
response.PutChar(';');
}
+ // Flags
+ MemoryRegionInfo::OptionalBool memory_tagged =
+ region_info.GetMemoryTagged();
+ if (memory_tagged != MemoryRegionInfo::eDontKnow) {
+ response.PutCString("flags:");
+ if (memory_tagged == MemoryRegionInfo::eYes) {
+ response.PutCString("mt");
+ }
+ response.PutChar(';');
+ }
+
// Name
ConstString name = region_info.GetName();
if (name) {
@@ -2773,10 +2941,11 @@ GDBRemoteCommunicationServerLLGS::BuildTargetXml() {
continue;
}
- response.Printf("<reg name=\"%s\" bitsize=\"%" PRIu32 "\" offset=\"%" PRIu32
- "\" regnum=\"%d\" ",
- reg_info->name, reg_info->byte_size * 8,
- reg_info->byte_offset, reg_index);
+ response.Printf("<reg name=\"%s\" bitsize=\"%" PRIu32 "\" regnum=\"%d\" ",
+ reg_info->name, reg_info->byte_size * 8, reg_index);
+
+ if (!reg_context.RegisterOffsetIsDynamic())
+ response.Printf("offset=\"%" PRIu32 "\" ", reg_info->byte_offset);
if (reg_info->alt_name && reg_info->alt_name[0])
response.Printf("altname=\"%s\" ", reg_info->alt_name);
@@ -2876,8 +3045,7 @@ GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object,
if (object == "features" && annex == "target.xml")
return BuildTargetXml();
- return llvm::make_error<PacketUnimplementedError>(
- "Xfer object not supported");
+ return llvm::make_error<UnimplementedError>();
}
GDBRemoteCommunication::PacketResult
@@ -3099,6 +3267,72 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttach(
}
GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_vAttachWait(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Consume the ';' after the identifier.
+ packet.SetFilePos(strlen("vAttachWait"));
+
+ if (!packet.GetBytesLeft() || packet.GetChar() != ';')
+ return SendIllFormedResponse(packet, "vAttachWait missing expected ';'");
+
+ // Allocate the buffer for the process name from vAttachWait.
+ std::string process_name;
+ if (!packet.GetHexByteString(process_name))
+ return SendIllFormedResponse(packet,
+ "vAttachWait failed to parse process name");
+
+ LLDB_LOG(log, "attempting to attach to process named '{0}'", process_name);
+
+ Status error = AttachWaitProcess(process_name, false);
+ if (error.Fail()) {
+ LLDB_LOG(log, "failed to attach to process named '{0}': {1}", process_name,
+ error);
+ return SendErrorResponse(error);
+ }
+
+ // Notify we attached by sending a stop packet.
+ return SendStopReasonForState(m_debugged_process_up->GetState());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_qVAttachOrWaitSupported(
+ StringExtractorGDBRemote &packet) {
+ return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Consume the ';' after the identifier.
+ packet.SetFilePos(strlen("vAttachOrWait"));
+
+ if (!packet.GetBytesLeft() || packet.GetChar() != ';')
+ return SendIllFormedResponse(packet, "vAttachOrWait missing expected ';'");
+
+ // Allocate the buffer for the process name from vAttachWait.
+ std::string process_name;
+ if (!packet.GetHexByteString(process_name))
+ return SendIllFormedResponse(packet,
+ "vAttachOrWait failed to parse process name");
+
+ LLDB_LOG(log, "attempting to attach to process named '{0}'", process_name);
+
+ Status error = AttachWaitProcess(process_name, true);
+ if (error.Fail()) {
+ LLDB_LOG(log, "failed to attach to process named '{0}': {1}", process_name,
+ error);
+ return SendErrorResponse(error);
+ }
+
+ // Notify we attached by sending a stop packet.
+ return SendStopReasonForState(m_debugged_process_up->GetState());
+}
+
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index 3ce285910c25..c51139924559 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -59,6 +59,17 @@ public:
/// attach operation.
Status AttachToProcess(lldb::pid_t pid);
+ /// Wait to attach to a process with a given name.
+ ///
+ /// This method supports waiting for the next instance of a process
+ /// with a given name and attaching llgs to that via the configured
+ /// Platform.
+ ///
+ /// \return
+ /// An Status object indicating the success or failure of the
+ /// attach operation.
+ Status AttachWaitProcess(llvm::StringRef process_name, bool include_existing);
+
// NativeProcessProtocol::NativeDelegate overrides
void InitializeDelegate(NativeProcessProtocol *process) override;
@@ -138,6 +149,8 @@ protected:
PacketResult Handle_memory_read(StringExtractorGDBRemote &packet);
PacketResult Handle_M(StringExtractorGDBRemote &packet);
+ PacketResult Handle__M(StringExtractorGDBRemote &packet);
+ PacketResult Handle__m(StringExtractorGDBRemote &packet);
PacketResult
Handle_qMemoryRegionInfoSupported(StringExtractorGDBRemote &packet);
@@ -162,10 +175,18 @@ protected:
PacketResult Handle_jTraceConfigRead(StringExtractorGDBRemote &packet);
+ PacketResult Handle_jLLDBTraceSupportedType(StringExtractorGDBRemote &packet);
+
PacketResult Handle_QRestoreRegisterState(StringExtractorGDBRemote &packet);
PacketResult Handle_vAttach(StringExtractorGDBRemote &packet);
+ PacketResult Handle_vAttachWait(StringExtractorGDBRemote &packet);
+
+ PacketResult Handle_qVAttachOrWaitSupported(StringExtractorGDBRemote &packet);
+
+ PacketResult Handle_vAttachOrWait(StringExtractorGDBRemote &packet);
+
PacketResult Handle_D(StringExtractorGDBRemote &packet);
PacketResult Handle_qThreadStopInfo(StringExtractorGDBRemote &packet);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index d14b79a03d17..3462fb7ec8b9 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -26,12 +26,14 @@
#include "lldb/Host/FileAction.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StructuredData.h"
+#include "lldb/Utility/TildeExpressionResolver.h"
#include "lldb/Utility/UriParser.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"
@@ -40,6 +42,69 @@ using namespace lldb;
using namespace lldb_private::process_gdb_remote;
using namespace lldb_private;
+GDBRemoteCommunicationServerPlatform::PortMap::PortMap(uint16_t min_port,
+ uint16_t max_port) {
+ for (; min_port < max_port; ++min_port)
+ m_port_map[min_port] = LLDB_INVALID_PROCESS_ID;
+}
+
+void GDBRemoteCommunicationServerPlatform::PortMap::AllowPort(uint16_t port) {
+ // Do not modify existing mappings
+ m_port_map.insert({port, LLDB_INVALID_PROCESS_ID});
+}
+
+llvm::Expected<uint16_t>
+GDBRemoteCommunicationServerPlatform::PortMap::GetNextAvailablePort() {
+ if (m_port_map.empty())
+ return 0; // Bind to port zero and get a port, we didn't have any
+ // limitations
+
+ for (auto &pair : m_port_map) {
+ if (pair.second == LLDB_INVALID_PROCESS_ID) {
+ pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID;
+ return pair.first;
+ }
+ }
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "No free port found in port map");
+}
+
+bool GDBRemoteCommunicationServerPlatform::PortMap::AssociatePortWithProcess(
+ uint16_t port, lldb::pid_t pid) {
+ auto pos = m_port_map.find(port);
+ if (pos != m_port_map.end()) {
+ pos->second = pid;
+ return true;
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationServerPlatform::PortMap::FreePort(uint16_t port) {
+ std::map<uint16_t, lldb::pid_t>::iterator pos = m_port_map.find(port);
+ if (pos != m_port_map.end()) {
+ pos->second = LLDB_INVALID_PROCESS_ID;
+ return true;
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationServerPlatform::PortMap::FreePortForProcess(
+ lldb::pid_t pid) {
+ if (!m_port_map.empty()) {
+ for (auto &pair : m_port_map) {
+ if (pair.second == pid) {
+ pair.second = LLDB_INVALID_PROCESS_ID;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool GDBRemoteCommunicationServerPlatform::PortMap::empty() const {
+ return m_port_map.empty();
+}
+
// GDBRemoteCommunicationServerPlatform constructor
GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(
const Socket::SocketProtocol socket_protocol, const char *socket_scheme)
@@ -69,6 +134,9 @@ GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(
StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
&GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo);
RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qPathComplete,
+ &GDBRemoteCommunicationServerPlatform::Handle_qPathComplete);
+ RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
&GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir);
RegisterMemberFunctionHandler(
@@ -89,9 +157,14 @@ GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() {}
Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
const lldb_private::Args &args, std::string hostname, lldb::pid_t &pid,
- uint16_t &port, std::string &socket_name) {
- if (port == UINT16_MAX)
- port = GetNextAvailablePort();
+ llvm::Optional<uint16_t> &port, std::string &socket_name) {
+ if (!port) {
+ llvm::Expected<uint16_t> available_port = m_port_map.GetNextAvailablePort();
+ if (available_port)
+ port = *available_port;
+ else
+ return Status(available_port.takeError());
+ }
// Spawn a new thread to accept the port that gets bound after binding to
// port 0 (zero).
@@ -106,7 +179,7 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
LLDB_LOGF(log, "Launching debugserver with: %s:%u...", hostname.c_str(),
- port);
+ *port);
// Do not run in a new session so that it can not linger after the platform
// closes.
@@ -121,7 +194,7 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
#if !defined(__APPLE__)
url << m_socket_scheme << "://";
#endif
- uint16_t *port_ptr = &port;
+ uint16_t *port_ptr = port.getPointer();
if (m_socket_protocol == Socket::ProtocolTcp) {
llvm::StringRef platform_scheme;
llvm::StringRef platform_ip;
@@ -132,7 +205,7 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
platform_port, platform_path);
UNUSED_IF_ASSERT_DISABLED(ok);
assert(ok);
- url << platform_ip.str() << ":" << port;
+ url << '[' << platform_ip.str() << "]:" << *port;
} else {
socket_name = GetDomainSocketPath("gdbserver").GetPath();
url << socket_name;
@@ -146,11 +219,11 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
if (pid != LLDB_INVALID_PROCESS_ID) {
std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
m_spawned_pids.insert(pid);
- if (port > 0)
- AssociatePortWithProcess(port, pid);
+ if (*port > 0)
+ m_port_map.AssociatePortWithProcess(*port, pid);
} else {
- if (port > 0)
- FreePort(port);
+ if (*port > 0)
+ m_port_map.FreePort(*port);
}
return error;
}
@@ -170,12 +243,15 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
packet.SetFilePos(::strlen("qLaunchGDBServer;"));
llvm::StringRef name;
llvm::StringRef value;
- uint16_t port = UINT16_MAX;
+ llvm::Optional<uint16_t> port;
while (packet.GetNameColonValue(name, value)) {
if (name.equals("host"))
hostname = std::string(value);
- else if (name.equals("port"))
- value.getAsInteger(0, port);
+ else if (name.equals("port")) {
+ // Make the Optional valid so we can use its value
+ port = 0;
+ value.getAsInteger(0, port.getValue());
+ }
}
lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
@@ -196,8 +272,9 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
__FUNCTION__, debugserver_pid);
StreamGDBRemote response;
+ assert(port);
response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid,
- port + m_port_offset);
+ *port + m_port_offset);
if (!socket_name.empty()) {
response.PutCString("socket_name:");
response.PutStringAsRawHex8(socket_name);
@@ -334,6 +411,38 @@ GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo(
}
GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerPlatform::Handle_qPathComplete(
+ StringExtractorGDBRemote &packet) {
+ packet.SetFilePos(::strlen("qPathComplete:"));
+ const bool only_dir = (packet.GetHexMaxU32(false, 0) == 1);
+ if (packet.GetChar() != ',')
+ return SendErrorResponse(85);
+ std::string path;
+ packet.GetHexByteString(path);
+
+ StringList matches;
+ StandardTildeExpressionResolver resolver;
+ if (only_dir)
+ CommandCompletions::DiskDirectories(path, matches, resolver);
+ else
+ CommandCompletions::DiskFiles(path, matches, resolver);
+
+ StreamString response;
+ response.PutChar('M');
+ llvm::StringRef separator;
+ std::sort(matches.begin(), matches.end());
+ for (const auto &match : matches) {
+ response << separator;
+ separator = ",";
+ // encode result strings into hex bytes to avoid unexpected error caused by
+ // special characters like '$'.
+ response.PutStringAsRawHex8(match.c_str());
+ }
+
+ return SendPacketNoLock(response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir(
StringExtractorGDBRemote &packet) {
@@ -416,7 +525,7 @@ GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(
bool GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped(
lldb::pid_t pid) {
std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
- FreePortForProcess(pid);
+ m_port_map.FreePortForProcess(pid);
m_spawned_pids.erase(pid);
return true;
}
@@ -462,51 +571,6 @@ void GDBRemoteCommunicationServerPlatform::SetPortMap(PortMap &&port_map) {
m_port_map = port_map;
}
-uint16_t GDBRemoteCommunicationServerPlatform::GetNextAvailablePort() {
- if (m_port_map.empty())
- return 0; // Bind to port zero and get a port, we didn't have any
- // limitations
-
- for (auto &pair : m_port_map) {
- if (pair.second == LLDB_INVALID_PROCESS_ID) {
- pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID;
- return pair.first;
- }
- }
- return UINT16_MAX;
-}
-
-bool GDBRemoteCommunicationServerPlatform::AssociatePortWithProcess(
- uint16_t port, lldb::pid_t pid) {
- PortMap::iterator pos = m_port_map.find(port);
- if (pos != m_port_map.end()) {
- pos->second = pid;
- return true;
- }
- return false;
-}
-
-bool GDBRemoteCommunicationServerPlatform::FreePort(uint16_t port) {
- PortMap::iterator pos = m_port_map.find(port);
- if (pos != m_port_map.end()) {
- pos->second = LLDB_INVALID_PROCESS_ID;
- return true;
- }
- return false;
-}
-
-bool GDBRemoteCommunicationServerPlatform::FreePortForProcess(lldb::pid_t pid) {
- if (!m_port_map.empty()) {
- for (auto &pair : m_port_map) {
- if (pair.second == pid) {
- pair.second = LLDB_INVALID_PROCESS_ID;
- return true;
- }
- }
- }
- return false;
-}
-
const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() {
static FileSpec g_domainsocket_dir;
static llvm::once_flag g_once_flag;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
index a8cacea78835..6b964da4a279 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
@@ -16,13 +16,61 @@
#include "GDBRemoteCommunicationServerCommon.h"
#include "lldb/Host/Socket.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/Error.h"
+
namespace lldb_private {
namespace process_gdb_remote {
class GDBRemoteCommunicationServerPlatform
: public GDBRemoteCommunicationServerCommon {
public:
- typedef std::map<uint16_t, lldb::pid_t> PortMap;
+ class PortMap {
+ public:
+ // This class is used to restrict the range of ports that
+ // platform created debugserver/gdbserver processes will
+ // communicate on.
+
+ // Construct an empty map, where empty means any port is allowed.
+ PortMap() = default;
+
+ // Make a port map with a range of free ports
+ // from min_port to max_port-1.
+ PortMap(uint16_t min_port, uint16_t max_port);
+
+ // Add a port to the map. If it is already in the map do not modify
+ // its mapping. (used ports remain used, new ports start as free)
+ void AllowPort(uint16_t port);
+
+ // If we are using a port map where we can only use certain ports,
+ // get the next available port.
+ //
+ // If we are using a port map and we are out of ports, return an error.
+ //
+ // If we aren't using a port map, return 0 to indicate we should bind to
+ // port 0 and then figure out which port we used.
+ llvm::Expected<uint16_t> GetNextAvailablePort();
+
+ // Tie a port to a process ID. Returns false if the port is not in the port
+ // map. If the port is already in use it will be moved to the given pid.
+ // FIXME: This is and GetNextAvailablePort make create a race condition if
+ // the portmap is shared between processes.
+ bool AssociatePortWithProcess(uint16_t port, lldb::pid_t pid);
+
+ // Free the given port. Returns false if the port is not in the map.
+ bool FreePort(uint16_t port);
+
+ // Free the port associated with the given pid. Returns false if there is
+ // no port associated with the pid.
+ bool FreePortForProcess(lldb::pid_t pid);
+
+ // Returns true if there are no ports in the map, regardless of the state
+ // of those ports. Meaning a map with 1 used port is not empty.
+ bool empty() const;
+
+ private:
+ std::map<uint16_t, lldb::pid_t> m_port_map;
+ };
GDBRemoteCommunicationServerPlatform(
const Socket::SocketProtocol socket_protocol, const char *socket_scheme);
@@ -35,27 +83,14 @@ public:
// a port chosen by the OS.
void SetPortMap(PortMap &&port_map);
- // If we are using a port map where we can only use certain ports,
- // get the next available port.
- //
- // If we are using a port map and we are out of ports, return UINT16_MAX
- //
- // If we aren't using a port map, return 0 to indicate we should bind to
- // port 0 and then figure out which port we used.
- uint16_t GetNextAvailablePort();
-
- bool AssociatePortWithProcess(uint16_t port, lldb::pid_t pid);
-
- bool FreePort(uint16_t port);
-
- bool FreePortForProcess(lldb::pid_t pid);
-
void SetPortOffset(uint16_t port_offset);
void SetInferiorArguments(const lldb_private::Args &args);
+ // Set port if you want to use a specific port number.
+ // Otherwise port will be set to the port that was chosen for you.
Status LaunchGDBServer(const lldb_private::Args &args, std::string hostname,
- lldb::pid_t &pid, uint16_t &port,
+ lldb::pid_t &pid, llvm::Optional<uint16_t> &port,
std::string &socket_name);
void SetPendingGdbServer(lldb::pid_t pid, uint16_t port,
@@ -81,6 +116,8 @@ protected:
PacketResult Handle_qKillSpawnedProcess(StringExtractorGDBRemote &packet);
+ PacketResult Handle_qPathComplete(StringExtractorGDBRemote &packet);
+
PacketResult Handle_qProcessInfo(StringExtractorGDBRemote &packet);
PacketResult Handle_qGetWorkingDir(StringExtractorGDBRemote &packet);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index 1f31b45d0fa9..10006616b0c6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -31,19 +31,20 @@ using namespace lldb_private::process_gdb_remote;
// GDBRemoteRegisterContext constructor
GDBRemoteRegisterContext::GDBRemoteRegisterContext(
ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
- GDBRemoteDynamicRegisterInfo &reg_info, bool read_all_at_once,
+ GDBRemoteDynamicRegisterInfoSP reg_info_sp, bool read_all_at_once,
bool write_all_at_once)
- : RegisterContext(thread, concrete_frame_idx), m_reg_info(reg_info),
- m_reg_valid(), m_reg_data(), m_read_all_at_once(read_all_at_once),
+ : RegisterContext(thread, concrete_frame_idx),
+ m_reg_info_sp(std::move(reg_info_sp)), m_reg_valid(), m_reg_data(),
+ m_read_all_at_once(read_all_at_once),
m_write_all_at_once(write_all_at_once) {
// Resize our vector of bools to contain one bool for every register. We will
// use these boolean values to know when a register value is valid in
// m_reg_data.
- m_reg_valid.resize(reg_info.GetNumRegisters());
+ m_reg_valid.resize(m_reg_info_sp->GetNumRegisters());
// Make a heap based buffer that is big enough to store all registers
DataBufferSP reg_data_sp(
- new DataBufferHeap(reg_info.GetRegisterDataByteSize(), 0));
+ new DataBufferHeap(m_reg_info_sp->GetRegisterDataByteSize(), 0));
m_reg_data.SetData(reg_data_sp);
m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder());
}
@@ -62,12 +63,12 @@ void GDBRemoteRegisterContext::SetAllRegisterValid(bool b) {
}
size_t GDBRemoteRegisterContext::GetRegisterCount() {
- return m_reg_info.GetNumRegisters();
+ return m_reg_info_sp->GetNumRegisters();
}
const RegisterInfo *
GDBRemoteRegisterContext::GetRegisterInfoAtIndex(size_t reg) {
- RegisterInfo *reg_info = m_reg_info.GetRegisterInfoAtIndex(reg);
+ RegisterInfo *reg_info = m_reg_info_sp->GetRegisterInfoAtIndex(reg);
if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes) {
const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture();
@@ -78,11 +79,11 @@ GDBRemoteRegisterContext::GetRegisterInfoAtIndex(size_t reg) {
}
size_t GDBRemoteRegisterContext::GetRegisterSetCount() {
- return m_reg_info.GetNumRegisterSets();
+ return m_reg_info_sp->GetNumRegisterSets();
}
const RegisterSet *GDBRemoteRegisterContext::GetRegisterSet(size_t reg_set) {
- return m_reg_info.GetRegisterSet(reg_set);
+ return m_reg_info_sp->GetRegisterSet(reg_set);
}
bool GDBRemoteRegisterContext::ReadRegister(const RegisterInfo *reg_info,
@@ -209,11 +210,12 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
SetAllRegisterValid(true);
return true;
} else if (buffer_sp->GetByteSize() > 0) {
- const int regcount = m_reg_info.GetNumRegisters();
+ const int regcount = m_reg_info_sp->GetNumRegisters();
for (int i = 0; i < regcount; i++) {
- struct RegisterInfo *reginfo = m_reg_info.GetRegisterInfoAtIndex(i);
- if (reginfo->byte_offset + reginfo->byte_size
- <= buffer_sp->GetByteSize()) {
+ struct RegisterInfo *reginfo =
+ m_reg_info_sp->GetRegisterInfoAtIndex(i);
+ if (reginfo->byte_offset + reginfo->byte_size <=
+ buffer_sp->GetByteSize()) {
m_reg_valid[i] = true;
} else {
m_reg_valid[i] = false;
@@ -342,6 +344,15 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
if (dst == nullptr)
return false;
+ // Code below is specific to AArch64 target in SVE state
+ // If vector granule (vg) register is being written then thread's
+ // register context reconfiguration is triggered on success.
+ bool do_reconfigure_arm64_sve = false;
+ const ArchSpec &arch = process->GetTarget().GetArchitecture();
+ if (arch.IsValid() && arch.GetTriple().isAArch64())
+ if (strcmp(reg_info->name, "vg") == 0)
+ do_reconfigure_arm64_sve = true;
+
if (data.CopyByteOrderedData(data_offset, // src offset
reg_info->byte_size, // src length
dst, // dst
@@ -361,6 +372,10 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
{
SetAllRegisterValid(false);
+
+ if (do_reconfigure_arm64_sve)
+ AArch64SVEReconfigure();
+
return true;
}
} else {
@@ -389,6 +404,9 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
} else {
// This is an actual register, write it
success = SetPrimordialRegister(reg_info, gdb_comm);
+
+ if (success && do_reconfigure_arm64_sve)
+ AArch64SVEReconfigure();
}
// Check if writing this register will invalidate any other register
@@ -506,7 +524,7 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues(
// m_reg_data buffer
}
data_sp = std::make_shared<DataBufferHeap>(
- m_reg_data.GetDataStart(), m_reg_info.GetRegisterDataByteSize());
+ m_reg_data.GetDataStart(), m_reg_info_sp->GetRegisterDataByteSize());
return true;
} else {
@@ -654,9 +672,8 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
if (m_thread.GetProcess().get()) {
const ArchSpec &arch =
m_thread.GetProcess()->GetTarget().GetArchitecture();
- if (arch.IsValid() &&
- (arch.GetMachine() == llvm::Triple::aarch64 ||
- arch.GetMachine() == llvm::Triple::aarch64_32) &&
+ if (arch.IsValid() && (arch.GetMachine() == llvm::Triple::aarch64 ||
+ arch.GetMachine() == llvm::Triple::aarch64_32) &&
arch.GetTriple().getVendor() == llvm::Triple::Apple &&
arch.GetTriple().getOS() == llvm::Triple::IOS) {
arm64_debugserver = true;
@@ -708,7 +725,63 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
uint32_t GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber(
lldb::RegisterKind kind, uint32_t num) {
- return m_reg_info.ConvertRegisterKindToRegisterNumber(kind, num);
+ return m_reg_info_sp->ConvertRegisterKindToRegisterNumber(kind, num);
+}
+
+bool GDBRemoteRegisterContext::AArch64SVEReconfigure() {
+ if (!m_reg_info_sp)
+ return false;
+
+ const RegisterInfo *reg_info = m_reg_info_sp->GetRegisterInfo("vg");
+ if (!reg_info)
+ return false;
+
+ uint64_t fail_value = LLDB_INVALID_ADDRESS;
+ uint32_t vg_reg_num = reg_info->kinds[eRegisterKindLLDB];
+ uint64_t vg_reg_value = ReadRegisterAsUnsigned(vg_reg_num, fail_value);
+
+ if (vg_reg_value != fail_value && vg_reg_value <= 32) {
+ const RegisterInfo *reg_info = m_reg_info_sp->GetRegisterInfo("p0");
+ if (!reg_info || vg_reg_value == reg_info->byte_size)
+ return false;
+
+ if (m_reg_info_sp->UpdateARM64SVERegistersInfos(vg_reg_value)) {
+ // Make a heap based buffer that is big enough to store all registers
+ m_reg_data.SetData(std::make_shared<DataBufferHeap>(
+ m_reg_info_sp->GetRegisterDataByteSize(), 0));
+ m_reg_data.SetByteOrder(GetByteOrder());
+
+ InvalidateAllRegisters();
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool GDBRemoteDynamicRegisterInfo::UpdateARM64SVERegistersInfos(uint64_t vg) {
+ // SVE Z register size is vg x 8 bytes.
+ uint32_t z_reg_byte_size = vg * 8;
+
+ // SVE vector length has changed, accordingly set size of Z, P and FFR
+ // registers. Also invalidate register offsets it will be recalculated
+ // after SVE register size update.
+ for (auto &reg : m_regs) {
+ if (reg.value_regs == nullptr) {
+ if (reg.name[0] == 'z' && isdigit(reg.name[1]))
+ reg.byte_size = z_reg_byte_size;
+ else if (reg.name[0] == 'p' && isdigit(reg.name[1]))
+ reg.byte_size = vg;
+ else if (strcmp(reg.name, "ffr") == 0)
+ reg.byte_size = vg;
+ }
+ reg.byte_offset = LLDB_INVALID_INDEX32;
+ }
+
+ // Re-calculate register offsets
+ ConfigureOffsets();
+ return true;
}
void GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
index 015862587103..252d7b359ee8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
@@ -27,20 +27,25 @@ namespace process_gdb_remote {
class ThreadGDBRemote;
class ProcessGDBRemote;
+class GDBRemoteDynamicRegisterInfo;
-class GDBRemoteDynamicRegisterInfo : public DynamicRegisterInfo {
+typedef std::shared_ptr<GDBRemoteDynamicRegisterInfo>
+ GDBRemoteDynamicRegisterInfoSP;
+
+class GDBRemoteDynamicRegisterInfo final : public DynamicRegisterInfo {
public:
GDBRemoteDynamicRegisterInfo() : DynamicRegisterInfo() {}
~GDBRemoteDynamicRegisterInfo() override = default;
void HardcodeARMRegisters(bool from_scratch);
+ bool UpdateARM64SVERegistersInfos(uint64_t vg);
};
class GDBRemoteRegisterContext : public RegisterContext {
public:
GDBRemoteRegisterContext(ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
- GDBRemoteDynamicRegisterInfo &reg_info,
+ GDBRemoteDynamicRegisterInfoSP reg_info_sp,
bool read_all_at_once, bool write_all_at_once);
~GDBRemoteRegisterContext() override;
@@ -73,6 +78,8 @@ public:
uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
uint32_t num) override;
+ bool AArch64SVEReconfigure();
+
protected:
friend class ThreadGDBRemote;
@@ -106,7 +113,7 @@ protected:
m_reg_valid[reg] = valid;
}
- GDBRemoteDynamicRegisterInfo &m_reg_info;
+ GDBRemoteDynamicRegisterInfoSP m_reg_info_sp;
std::vector<bool> m_reg_valid;
DataExtractor m_reg_data;
bool m_read_all_at_once;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index b03184b41abb..1214812b60b0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -207,7 +207,8 @@ void ProcessGDBRemote::Terminate() {
lldb::ProcessSP
ProcessGDBRemote::CreateInstance(lldb::TargetSP target_sp,
ListenerSP listener_sp,
- const FileSpec *crash_file_path) {
+ const FileSpec *crash_file_path,
+ bool can_connect) {
lldb::ProcessSP process_sp;
if (crash_file_path == nullptr)
process_sp = std::make_shared<ProcessGDBRemote>(target_sp, listener_sp);
@@ -250,7 +251,7 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
ListenerSP listener_sp)
: Process(target_sp, listener_sp),
m_debugserver_pid(LLDB_INVALID_PROCESS_ID), m_last_stop_packet_mutex(),
- m_register_info(),
+ m_register_info_sp(nullptr),
m_async_broadcaster(nullptr, "lldb.process.gdb-remote.async-broadcaster"),
m_async_listener_sp(
Listener::MakeListener("lldb.process.gdb-remote.async-listener")),
@@ -369,8 +370,8 @@ bool ProcessGDBRemote::ParsePythonTargetDefinition(
m_breakpoint_pc_offset = breakpoint_pc_int_value->GetValue();
}
- if (m_register_info.SetRegisterInfo(*target_definition_sp,
- GetTarget().GetArchitecture()) > 0) {
+ if (m_register_info_sp->SetRegisterInfo(
+ *target_definition_sp, GetTarget().GetArchitecture()) > 0) {
return true;
}
}
@@ -397,10 +398,10 @@ static size_t SplitCommaSeparatedRegisterNumberString(
}
void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
- if (!force && m_register_info.GetNumRegisters() > 0)
+ if (!force && m_register_info_sp)
return;
- m_register_info.Clear();
+ m_register_info_sp = std::make_shared<GDBRemoteDynamicRegisterInfo>();
// Check if qHostInfo specified a specific packet timeout for this
// connection. If so then lets update our setting so the user knows what the
@@ -452,7 +453,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
return;
char packet[128];
- uint32_t reg_offset = 0;
+ uint32_t reg_offset = LLDB_INVALID_INDEX32;
uint32_t reg_num = 0;
for (StringExtractorGDBRemote::ResponseType response_type =
StringExtractorGDBRemote::eResponse;
@@ -565,7 +566,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
reg_info.byte_offset = reg_offset;
assert(reg_info.byte_size != 0);
- reg_offset += reg_info.byte_size;
+ reg_offset = LLDB_INVALID_INDEX32;
if (!value_regs.empty()) {
value_regs.push_back(LLDB_INVALID_REGNUM);
reg_info.value_regs = value_regs.data();
@@ -582,7 +583,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
if (ABISP abi_sp = ABI::FindPlugin(shared_from_this(), arch_to_use))
abi_sp->AugmentRegisterInfo(reg_info);
- m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
+ m_register_info_sp->AddRegister(reg_info, reg_name, alt_name, set_name);
} else {
break; // ensure exit before reg_num is incremented
}
@@ -591,8 +592,8 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
}
}
- if (m_register_info.GetNumRegisters() > 0) {
- m_register_info.Finalize(GetTarget().GetArchitecture());
+ if (m_register_info_sp->GetNumRegisters() > 0) {
+ m_register_info_sp->Finalize(GetTarget().GetArchitecture());
return;
}
@@ -601,21 +602,21 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
// updated debugserver down on the devices. On the other hand, if the
// accumulated reg_num is positive, see if we can add composite registers to
// the existing primordial ones.
- bool from_scratch = (m_register_info.GetNumRegisters() == 0);
+ bool from_scratch = (m_register_info_sp->GetNumRegisters() == 0);
if (!target_arch.IsValid()) {
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);
+ m_register_info_sp->HardcodeARMRegisters(from_scratch);
} else if (target_arch.GetMachine() == llvm::Triple::arm ||
target_arch.GetMachine() == llvm::Triple::thumb) {
- m_register_info.HardcodeARMRegisters(from_scratch);
+ m_register_info_sp->HardcodeARMRegisters(from_scratch);
}
// At this point, we can finalize our register info.
- m_register_info.Finalize(GetTarget().GetArchitecture());
+ m_register_info_sp->Finalize(GetTarget().GetArchitecture());
}
Status ProcessGDBRemote::WillLaunch(lldb_private::Module *module) {
@@ -819,8 +820,8 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
// since 'O' packets can really slow down debugging if the inferior
// does a lot of output.
if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
- pty.OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY, nullptr, 0)) {
- FileSpec secondary_name{pty.GetSecondaryName(nullptr, 0)};
+ !errorToBool(pty.OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY))) {
+ FileSpec secondary_name(pty.GetSecondaryName());
if (!stdin_file_spec)
stdin_file_spec = secondary_name;
@@ -1226,6 +1227,10 @@ Status ProcessGDBRemote::GetTraceConfig(lldb::user_id_t uid,
return m_gdb_comm.SendGetTraceConfigPacket(uid, options);
}
+llvm::Expected<TraceTypeInfo> ProcessGDBRemote::GetSupportedTraceType() {
+ return m_gdb_comm.SendGetSupportedTraceType();
+}
+
void ProcessGDBRemote::DidExit() {
// When we exit, disconnect from the GDB server communications
m_gdb_comm.Disconnect();
@@ -1599,8 +1604,8 @@ bool ProcessGDBRemote::UpdateThreadIDList() {
return true;
}
-bool ProcessGDBRemote::UpdateThreadList(ThreadList &old_thread_list,
- ThreadList &new_thread_list) {
+bool ProcessGDBRemote::DoUpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
// locker will keep a mutex locked until it goes out of scope
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_THREAD));
LLDB_LOGV(log, "pid = {0}", GetID());
@@ -1760,6 +1765,19 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
gdb_thread->PrivateSetRegisterValue(pair.first, buffer_sp->GetData());
}
+ // AArch64 SVE specific code below calls AArch64SVEReconfigure to update
+ // SVE register sizes and offsets if value of VG register has changed
+ // since last stop.
+ const ArchSpec &arch = GetTarget().GetArchitecture();
+ if (arch.IsValid() && arch.GetTriple().isAArch64()) {
+ GDBRemoteRegisterContext *reg_ctx_sp =
+ static_cast<GDBRemoteRegisterContext *>(
+ gdb_thread->GetRegisterContext().get());
+
+ if (reg_ctx_sp)
+ reg_ctx_sp->AArch64SVEReconfigure();
+ }
+
thread_sp->SetName(thread_name.empty() ? nullptr : thread_name.c_str());
gdb_thread->SetThreadDispatchQAddr(thread_dispatch_qaddr);
@@ -2651,7 +2669,7 @@ addr_t ProcessGDBRemote::GetImageInfoAddress() {
llvm::Expected<LoadedModuleInfoList> list = GetLoadedModuleList();
if (!list) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- LLDB_LOG_ERROR(log, list.takeError(), "Failed to read module list: {0}");
+ LLDB_LOG_ERROR(log, list.takeError(), "Failed to read module list: {0}.");
} else {
addr = list->m_link_map;
}
@@ -3208,14 +3226,8 @@ Status ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) {
break;
case BreakpointSite::eExternal: {
- GDBStoppointType stoppoint_type;
- if (bp_site->IsHardware())
- stoppoint_type = eBreakpointHardware;
- else
- stoppoint_type = eBreakpointSoftware;
-
- if (m_gdb_comm.SendGDBStoppointTypePacket(stoppoint_type, false, addr,
- bp_op_size))
+ if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, false,
+ addr, bp_op_size))
error.SetErrorToGenericError();
} break;
}
@@ -4281,14 +4293,14 @@ struct GdbServerTargetInfo {
bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
GDBRemoteDynamicRegisterInfo &dyn_reg_info, ABISP abi_sp,
- uint32_t &cur_reg_num, uint32_t &reg_offset) {
+ uint32_t &reg_num_remote, uint32_t &reg_num_local) {
if (!feature_node)
return false;
+ uint32_t reg_offset = LLDB_INVALID_INDEX32;
feature_node.ForEachChildElementWithName(
- "reg",
- [&target_info, &dyn_reg_info, &cur_reg_num, &reg_offset,
- &abi_sp](const XMLNode &reg_node) -> bool {
+ "reg", [&target_info, &dyn_reg_info, &reg_num_remote, &reg_num_local,
+ &reg_offset, &abi_sp](const XMLNode &reg_node) -> bool {
std::string gdb_group;
std::string gdb_type;
ConstString reg_name;
@@ -4310,8 +4322,8 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
LLDB_INVALID_REGNUM, // eh_frame reg num
LLDB_INVALID_REGNUM, // DWARF reg num
LLDB_INVALID_REGNUM, // generic reg num
- cur_reg_num, // process plugin reg num
- cur_reg_num // native register number
+ reg_num_remote, // process plugin reg num
+ reg_num_local // native register number
},
nullptr,
nullptr,
@@ -4438,7 +4450,7 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
reg_info.byte_offset = reg_offset;
assert(reg_info.byte_size != 0);
- reg_offset += reg_info.byte_size;
+ reg_offset = LLDB_INVALID_INDEX32;
if (!value_regs.empty()) {
value_regs.push_back(LLDB_INVALID_REGNUM);
reg_info.value_regs = value_regs.data();
@@ -4448,7 +4460,8 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
reg_info.invalidate_regs = invalidate_regs.data();
}
- ++cur_reg_num;
+ reg_num_remote = reg_info.kinds[eRegisterKindProcessPlugin] + 1;
+ ++reg_num_local;
reg_info.name = reg_name.AsCString();
if (abi_sp)
abi_sp->AugmentRegisterInfo(reg_info);
@@ -4467,8 +4480,8 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
// for nested register definition files. It returns true if it was able
// to fetch and parse an xml file.
bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(
- ArchSpec &arch_to_use, std::string xml_filename, uint32_t &cur_reg_num,
- uint32_t &reg_offset) {
+ ArchSpec &arch_to_use, std::string xml_filename, uint32_t &reg_num_remote,
+ uint32_t &reg_num_local) {
// request the target xml file
std::string raw;
lldb_private::Status lldberr;
@@ -4571,13 +4584,13 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(
// ABI is also potentially incorrect.
ABISP abi_to_use_sp = ABI::FindPlugin(shared_from_this(), arch_to_use);
for (auto &feature_node : feature_nodes) {
- ParseRegisters(feature_node, target_info, this->m_register_info,
- abi_to_use_sp, cur_reg_num, reg_offset);
+ ParseRegisters(feature_node, target_info, *this->m_register_info_sp,
+ abi_to_use_sp, reg_num_remote, reg_num_local);
}
for (const auto &include : target_info.includes) {
- GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, include, cur_reg_num,
- reg_offset);
+ GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, include,
+ reg_num_remote, reg_num_local);
}
}
} else {
@@ -4597,12 +4610,13 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
if (!m_gdb_comm.GetQXferFeaturesReadSupported())
return false;
- uint32_t cur_reg_num = 0;
- uint32_t reg_offset = 0;
- if (GetGDBServerRegisterInfoXMLAndProcess (arch_to_use, "target.xml", cur_reg_num, reg_offset))
- this->m_register_info.Finalize(arch_to_use);
+ uint32_t reg_num_remote = 0;
+ uint32_t reg_num_local = 0;
+ if (GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, "target.xml",
+ reg_num_remote, reg_num_local))
+ this->m_register_info_sp->Finalize(arch_to_use);
- return m_register_info.GetNumRegisters() > 0;
+ return m_register_info_sp->GetNumRegisters() > 0;
}
llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() {
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index ba967727ae3b..0921bf17c4e4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -55,7 +55,8 @@ public:
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
lldb::ListenerSP listener_sp,
- const FileSpec *crash_file_path);
+ const FileSpec *crash_file_path,
+ bool can_connect);
static void Initialize();
@@ -175,6 +176,8 @@ public:
llvm::MutableArrayRef<uint8_t> &buffer,
size_t offset = 0) override;
+ llvm::Expected<TraceTypeInfo> GetSupportedTraceType() override;
+
Status GetTraceConfig(lldb::user_id_t uid, TraceOptions &options) override;
Status GetWatchpointSupportInfo(uint32_t &num, bool &after) override;
@@ -251,7 +254,7 @@ protected:
// the last stop
// packet variable
std::recursive_mutex m_last_stop_packet_mutex;
- GDBRemoteDynamicRegisterInfo m_register_info;
+ GDBRemoteDynamicRegisterInfoSP m_register_info_sp;
Broadcaster m_async_broadcaster;
lldb::ListenerSP m_async_listener_sp;
HostThread m_async_thread;
@@ -309,8 +312,8 @@ protected:
void Clear();
- bool UpdateThreadList(ThreadList &old_thread_list,
- ThreadList &new_thread_list) override;
+ bool DoUpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) override;
Status ConnectToReplayServer();
@@ -388,8 +391,8 @@ protected:
bool GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use,
std::string xml_filename,
- uint32_t &cur_reg_num,
- uint32_t &reg_offset);
+ uint32_t &cur_reg_remote,
+ uint32_t &cur_reg_local);
// Query remote GDBServer for register information
bool GetGDBServerRegisterInfo(ArchSpec &arch);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 6deabf8d5d71..2a9896e41085 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -42,6 +42,14 @@ ThreadGDBRemote::ThreadGDBRemote(Process &process, lldb::tid_t tid)
Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this, process.GetID(),
GetID());
+ // At this point we can clone reg_info for architectures supporting
+ // run-time update to register sizes and offsets..
+ auto &gdb_process = static_cast<ProcessGDBRemote &>(process);
+ if (!gdb_process.m_register_info_sp->IsReconfigurable())
+ m_reg_info_sp = gdb_process.m_register_info_sp;
+ else
+ m_reg_info_sp = std::make_shared<GDBRemoteDynamicRegisterInfo>(
+ *gdb_process.m_register_info_sp);
}
ThreadGDBRemote::~ThreadGDBRemote() {
@@ -307,8 +315,8 @@ ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) {
!pSupported || gdb_process->m_use_g_packet_for_reading;
bool write_all_registers_at_once = !pSupported;
reg_ctx_sp = std::make_shared<GDBRemoteRegisterContext>(
- *this, concrete_frame_idx, gdb_process->m_register_info,
- read_all_registers_at_once, write_all_registers_at_once);
+ *this, concrete_frame_idx, m_reg_info_sp, read_all_registers_at_once,
+ write_all_registers_at_once);
}
} else {
reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
index 5ad11170fec4..b7d75021c062 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
@@ -14,6 +14,8 @@
#include "lldb/Target/Thread.h"
#include "lldb/Utility/StructuredData.h"
+#include "GDBRemoteRegisterContext.h"
+
class StringExtractor;
namespace lldb_private {
@@ -101,6 +103,8 @@ protected:
m_queue_serial_number; // Queue info from stop reply/stop info for thread
lldb_private::LazyBool m_associated_with_libdispatch_queue;
+ GDBRemoteDynamicRegisterInfoSP m_reg_info_sp;
+
bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef<uint8_t> data);
bool PrivateSetRegisterValue(uint32_t reg, uint64_t regval);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
index 0c7f4cbbb859..61106ebcc430 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -62,27 +62,17 @@ UUID MinidumpParser::GetModuleUUID(const minidump::Module *module) {
static_cast<CvSignature>(static_cast<uint32_t>(*signature));
if (cv_signature == CvSignature::Pdb70) {
- const CvRecordPdb70 *pdb70_uuid = nullptr;
+ const UUID::CvRecordPdb70 *pdb70_uuid = nullptr;
Status error = consumeObject(cv_record, pdb70_uuid);
if (error.Fail())
return UUID();
-
- CvRecordPdb70 swapped;
- if (!GetArchitecture().GetTriple().isOSBinFormatELF()) {
- // LLDB's UUID class treats the data as a sequence of bytes, but breakpad
- // interprets it as a sequence of little-endian fields, which it converts
- // to big-endian when converting to text. Swap the bytes to big endian so
- // that the string representation comes out right.
- swapped = *pdb70_uuid;
- llvm::sys::swapByteOrder(swapped.Uuid.Data1);
- llvm::sys::swapByteOrder(swapped.Uuid.Data2);
- llvm::sys::swapByteOrder(swapped.Uuid.Data3);
- llvm::sys::swapByteOrder(swapped.Age);
- pdb70_uuid = &swapped;
+ if (GetArchitecture().GetTriple().isOSBinFormatELF()) {
+ if (pdb70_uuid->Age != 0)
+ return UUID::fromOptionalData(pdb70_uuid, sizeof(*pdb70_uuid));
+ return UUID::fromOptionalData(&pdb70_uuid->Uuid,
+ sizeof(pdb70_uuid->Uuid));
}
- if (pdb70_uuid->Age != 0)
- return UUID::fromOptionalData(pdb70_uuid, sizeof(*pdb70_uuid));
- return UUID::fromOptionalData(&pdb70_uuid->Uuid, sizeof(pdb70_uuid->Uuid));
+ return UUID::fromCvRecord(*pdb70_uuid);
} else if (cv_signature == CvSignature::ElfBuildId)
return UUID::fromOptionalData(cv_record);
@@ -267,6 +257,93 @@ llvm::ArrayRef<minidump::Module> MinidumpParser::GetModuleList() {
return {};
}
+static bool
+CreateRegionsCacheFromLinuxMaps(MinidumpParser &parser,
+ std::vector<MemoryRegionInfo> &regions) {
+ auto data = parser.GetStream(StreamType::LinuxMaps);
+ if (data.empty())
+ return false;
+
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+ ParseLinuxMapRegions(
+ llvm::toStringRef(data),
+ [&regions, &log](llvm::Expected<MemoryRegionInfo> region) -> bool {
+ if (region)
+ regions.push_back(*region);
+ else
+ LLDB_LOG_ERROR(log, region.takeError(),
+ "Reading memory region from minidump failed: {0}");
+ return true;
+ });
+ return !regions.empty();
+}
+
+/// Check for the memory regions starting at \a load_addr for a contiguous
+/// section that has execute permissions that matches the module path.
+///
+/// When we load a breakpad generated minidump file, we might have the
+/// /proc/<pid>/maps text for a process that details the memory map of the
+/// process that the minidump is describing. This checks the sorted memory
+/// regions for a section that has execute permissions. A sample maps files
+/// might look like:
+///
+/// 00400000-00401000 r--p 00000000 fd:01 2838574 /tmp/a.out
+/// 00401000-00402000 r-xp 00001000 fd:01 2838574 /tmp/a.out
+/// 00402000-00403000 r--p 00002000 fd:01 2838574 /tmp/a.out
+/// 00403000-00404000 r--p 00002000 fd:01 2838574 /tmp/a.out
+/// 00404000-00405000 rw-p 00003000 fd:01 2838574 /tmp/a.out
+/// ...
+///
+/// This function should return true when given 0x00400000 and "/tmp/a.out"
+/// is passed in as the path since it has a consecutive memory region for
+/// "/tmp/a.out" that has execute permissions at 0x00401000. This will help us
+/// differentiate if a file has been memory mapped into a process for reading
+/// and breakpad ends up saving a minidump file that has two module entries for
+/// a given file: one that is read only for the entire file, and then one that
+/// is the real executable that is loaded into memory for execution. For memory
+/// mapped files they will typically show up and r--p permissions and a range
+/// matcning the entire range of the file on disk:
+///
+/// 00800000-00805000 r--p 00000000 fd:01 2838574 /tmp/a.out
+/// 00805000-00806000 r-xp 00001000 fd:01 1234567 /usr/lib/libc.so
+///
+/// This function should return false when asked about 0x00800000 with
+/// "/tmp/a.out" as the path.
+///
+/// \param[in] path
+/// The path to the module to check for in the memory regions. Only sequential
+/// memory regions whose paths match this path will be considered when looking
+/// for execute permissions.
+///
+/// \param[in] regions
+/// A sorted list of memory regions obtained from a call to
+/// CreateRegionsCacheFromLinuxMaps.
+///
+/// \param[in] base_of_image
+/// The load address of this module from BaseOfImage in the modules list.
+///
+/// \return
+/// True if a contiguous region of memory belonging to the module with a
+/// matching path exists that has executable permissions. Returns false if
+/// \a regions is empty or if there are no regions with execute permissions
+/// that match \a path.
+
+static bool CheckForLinuxExecutable(ConstString path,
+ const MemoryRegionInfos &regions,
+ lldb::addr_t base_of_image) {
+ if (regions.empty())
+ return false;
+ lldb::addr_t addr = base_of_image;
+ MemoryRegionInfo region = MinidumpParser::GetMemoryRegionInfo(regions, addr);
+ while (region.GetName() == path) {
+ if (region.GetExecutable() == MemoryRegionInfo::eYes)
+ return true;
+ addr += region.GetRange().GetByteSize();
+ region = MinidumpParser::GetMemoryRegionInfo(regions, addr);
+ }
+ return false;
+}
+
std::vector<const minidump::Module *> MinidumpParser::GetFilteredModuleList() {
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES);
auto ExpectedModules = GetMinidumpFile().getModuleList();
@@ -276,6 +353,15 @@ std::vector<const minidump::Module *> MinidumpParser::GetFilteredModuleList() {
return {};
}
+ // Create memory regions from the linux maps only. We do this to avoid issues
+ // with breakpad generated minidumps where if someone has mmap'ed a shared
+ // library into memory to accesss its data in the object file, we can get a
+ // minidump with two mappings for a binary: one whose base image points to a
+ // memory region that is read + execute and one that is read only.
+ MemoryRegionInfos linux_regions;
+ if (CreateRegionsCacheFromLinuxMaps(*this, linux_regions))
+ llvm::sort(linux_regions);
+
// map module_name -> filtered_modules index
typedef llvm::StringMap<size_t> MapType;
MapType module_name_to_filtered_index;
@@ -304,10 +390,29 @@ std::vector<const minidump::Module *> MinidumpParser::GetFilteredModuleList() {
// "filtered_modules.size()" above.
filtered_modules.push_back(&module);
} else {
+ // We have a duplicate module entry. Check the linux regions to see if
+ // either module is not really a mapped executable. If one but not the
+ // other is a real mapped executable, prefer the executable one. This
+ // can happen when a process mmap's in the file for an executable in
+ // order to read bytes from the executable file. A memory region mapping
+ // will exist for the mmap'ed version and for the loaded executable, but
+ // only one will have a consecutive region that is executable in the
+ // memory regions.
+ auto dup_module = filtered_modules[iter->second];
+ ConstString name(*ExpectedName);
+ bool is_executable =
+ CheckForLinuxExecutable(name, linux_regions, module.BaseOfImage);
+ bool dup_is_executable =
+ CheckForLinuxExecutable(name, linux_regions, dup_module->BaseOfImage);
+
+ if (is_executable != dup_is_executable) {
+ if (is_executable)
+ filtered_modules[iter->second] = &module;
+ continue;
+ }
// This module has been seen. Modules are sometimes mentioned multiple
// times when they are mapped discontiguously, so find the module with
// the lowest "base_of_image" and use that as the filtered module.
- auto dup_module = filtered_modules[iter->second];
if (module.BaseOfImage < dup_module->BaseOfImage)
filtered_modules[iter->second] = &module;
}
@@ -412,22 +517,6 @@ llvm::ArrayRef<uint8_t> MinidumpParser::GetMemory(lldb::addr_t addr,
}
static bool
-CreateRegionsCacheFromLinuxMaps(MinidumpParser &parser,
- std::vector<MemoryRegionInfo> &regions) {
- auto data = parser.GetStream(StreamType::LinuxMaps);
- if (data.empty())
- return false;
- ParseLinuxMapRegions(llvm::toStringRef(data),
- [&](const lldb_private::MemoryRegionInfo &region,
- const lldb_private::Status &status) -> bool {
- if (status.Success())
- regions.push_back(region);
- return true;
- });
- return !regions.empty();
-}
-
-static bool
CreateRegionsCacheFromMemoryInfoList(MinidumpParser &parser,
std::vector<MemoryRegionInfo> &regions) {
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES);
@@ -500,10 +589,10 @@ CreateRegionsCacheFromMemory64List(MinidumpParser &parser,
uint64_t base_rva;
std::tie(memory64_list, base_rva) =
MinidumpMemoryDescriptor64::ParseMemory64List(data);
-
+
if (memory64_list.empty())
return false;
-
+
regions.reserve(memory64_list.size());
for (const auto &memory_desc : memory64_list) {
if (memory_desc.data_size == 0)
@@ -597,3 +686,30 @@ MinidumpParser::GetStreamTypeAsString(StreamType stream_type) {
}
return "unknown stream type";
}
+
+MemoryRegionInfo
+MinidumpParser::GetMemoryRegionInfo(const MemoryRegionInfos &regions,
+ lldb::addr_t load_addr) {
+ MemoryRegionInfo region;
+ auto pos = llvm::upper_bound(regions, load_addr);
+ if (pos != regions.begin() &&
+ std::prev(pos)->GetRange().Contains(load_addr)) {
+ return *std::prev(pos);
+ }
+
+ if (pos == regions.begin())
+ region.GetRange().SetRangeBase(0);
+ else
+ region.GetRange().SetRangeBase(std::prev(pos)->GetRange().GetRangeEnd());
+
+ if (pos == regions.end())
+ region.GetRange().SetRangeEnd(UINT64_MAX);
+ else
+ region.GetRange().SetRangeEnd(pos->GetRange().GetRangeBase());
+
+ region.SetReadable(MemoryRegionInfo::eNo);
+ region.SetWritable(MemoryRegionInfo::eNo);
+ region.SetExecutable(MemoryRegionInfo::eNo);
+ region.SetMapped(MemoryRegionInfo::eNo);
+ return region;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpParser.h
index c4d7612b5f8d..ff7134ff1815 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpParser.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpParser.h
@@ -96,6 +96,9 @@ public:
llvm::object::MinidumpFile &GetMinidumpFile() { return *m_file; }
+ static MemoryRegionInfo GetMemoryRegionInfo(const MemoryRegionInfos &regions,
+ lldb::addr_t load_addr);
+
private:
MinidumpParser(lldb::DataBufferSP data_sp,
std::unique_ptr<llvm::object::MinidumpFile> file);
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpTypes.h b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpTypes.h
index a7ac65120e2b..c05fcfef05a6 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpTypes.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/MinidumpTypes.h
@@ -40,21 +40,6 @@ enum class CvSignature : uint32_t {
ElfBuildId = 0x4270454c, // BpEL (Breakpad/Crashpad minidumps)
};
-// Reference:
-// https://crashpad.chromium.org/doxygen/structcrashpad_1_1CodeViewRecordPDB70.html
-struct CvRecordPdb70 {
- struct {
- llvm::support::ulittle32_t Data1;
- llvm::support::ulittle16_t Data2;
- llvm::support::ulittle16_t Data3;
- uint8_t Data4[8];
- } Uuid;
- llvm::support::ulittle32_t Age;
- // char PDBFileName[];
-};
-static_assert(sizeof(CvRecordPdb70) == 20,
- "sizeof CvRecordPdb70 is not correct!");
-
enum class MinidumpMiscInfoFlags : uint32_t {
ProcessID = (1 << 0),
ProcessTimes = (1 << 1),
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 1041f63aa2e2..05a48acc2f7a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -200,8 +200,9 @@ const char *ProcessMinidump::GetPluginDescriptionStatic() {
lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp,
lldb::ListenerSP listener_sp,
- const FileSpec *crash_file) {
- if (!crash_file)
+ const FileSpec *crash_file,
+ bool can_connect) {
+ if (!crash_file || can_connect)
return nullptr;
lldb::ProcessSP process_sp;
@@ -234,7 +235,7 @@ ProcessMinidump::ProcessMinidump(lldb::TargetSP target_sp,
lldb::ListenerSP listener_sp,
const FileSpec &core_file,
DataBufferSP core_data)
- : Process(target_sp, listener_sp), m_core_file(core_file),
+ : PostMortemProcess(target_sp, listener_sp), m_core_file(core_file),
m_core_data(std::move(core_data)), m_is_wow64(false) {}
ProcessMinidump::~ProcessMinidump() {
@@ -404,32 +405,6 @@ ArchSpec ProcessMinidump::GetArchitecture() {
return ArchSpec(triple);
}
-static MemoryRegionInfo GetMemoryRegionInfo(const MemoryRegionInfos &regions,
- lldb::addr_t load_addr) {
- MemoryRegionInfo region;
- auto pos = llvm::upper_bound(regions, load_addr);
- if (pos != regions.begin() &&
- std::prev(pos)->GetRange().Contains(load_addr)) {
- return *std::prev(pos);
- }
-
- if (pos == regions.begin())
- region.GetRange().SetRangeBase(0);
- else
- region.GetRange().SetRangeBase(std::prev(pos)->GetRange().GetRangeEnd());
-
- if (pos == regions.end())
- region.GetRange().SetRangeEnd(UINT64_MAX);
- else
- region.GetRange().SetRangeEnd(pos->GetRange().GetRangeBase());
-
- region.SetReadable(MemoryRegionInfo::eNo);
- region.SetWritable(MemoryRegionInfo::eNo);
- region.SetExecutable(MemoryRegionInfo::eNo);
- region.SetMapped(MemoryRegionInfo::eNo);
- return region;
-}
-
void ProcessMinidump::BuildMemoryRegions() {
if (m_memory_regions)
return;
@@ -454,7 +429,7 @@ void ProcessMinidump::BuildMemoryRegions() {
MemoryRegionInfo::RangeType section_range(load_addr,
section_sp->GetByteSize());
MemoryRegionInfo region =
- ::GetMemoryRegionInfo(*m_memory_regions, load_addr);
+ MinidumpParser::GetMemoryRegionInfo(*m_memory_regions, load_addr);
if (region.GetMapped() != MemoryRegionInfo::eYes &&
region.GetRange().GetRangeBase() <= section_range.GetRangeBase() &&
section_range.GetRangeEnd() <= region.GetRange().GetRangeEnd()) {
@@ -475,7 +450,7 @@ void ProcessMinidump::BuildMemoryRegions() {
Status ProcessMinidump::GetMemoryRegionInfo(lldb::addr_t load_addr,
MemoryRegionInfo &region) {
BuildMemoryRegions();
- region = ::GetMemoryRegionInfo(*m_memory_regions, load_addr);
+ region = MinidumpParser::GetMemoryRegionInfo(*m_memory_regions, load_addr);
return Status();
}
@@ -487,8 +462,8 @@ Status ProcessMinidump::GetMemoryRegions(MemoryRegionInfos &region_list) {
void ProcessMinidump::Clear() { Process::m_thread_list.Clear(); }
-bool ProcessMinidump::UpdateThreadList(ThreadList &old_thread_list,
- ThreadList &new_thread_list) {
+bool ProcessMinidump::DoUpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
for (const minidump::Thread &thread : m_thread_list) {
LocationDescriptor context_location = thread.Context;
diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
index bfdace7ea33e..27b0da0047a5 100644
--- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -12,7 +12,7 @@
#include "MinidumpParser.h"
#include "MinidumpTypes.h"
-#include "lldb/Target/Process.h"
+#include "lldb/Target/PostMortemProcess.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ConstString.h"
@@ -26,11 +26,12 @@ namespace lldb_private {
namespace minidump {
-class ProcessMinidump : public Process {
+class ProcessMinidump : public PostMortemProcess {
public:
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
lldb::ListenerSP listener_sp,
- const FileSpec *crash_file_path);
+ const FileSpec *crash_file_path,
+ bool can_connect);
static void Initialize();
@@ -97,8 +98,8 @@ public:
protected:
void Clear();
- bool UpdateThreadList(ThreadList &old_thread_list,
- ThreadList &new_thread_list) override;
+ bool DoUpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) override;
void ReadModuleList();
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
index acd6128d84c5..f14e2732f6eb 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
@@ -9,16 +9,66 @@
#include "Lua.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Utility/FileSpec.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/FormatVariadic.h"
using namespace lldb_private;
using namespace lldb;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
+
+// Disable warning C4190: 'LLDBSwigPythonBreakpointCallbackFunction' has
+// C-linkage specified, but returns UDT 'llvm::Expected<bool>' which is
+// incompatible with C
+#if _MSC_VER
+#pragma warning (push)
+#pragma warning (disable : 4190)
+#endif
+
+extern "C" llvm::Expected<bool> LLDBSwigLuaBreakpointCallbackFunction(
+ lua_State *L, lldb::StackFrameSP stop_frame_sp,
+ lldb::BreakpointLocationSP bp_loc_sp, StructuredDataImpl *extra_args_impl);
+
+#if _MSC_VER
+#pragma warning (pop)
+#endif
+
+#pragma clang diagnostic pop
+
+static int lldb_print(lua_State *L) {
+ int n = lua_gettop(L);
+ lua_getglobal(L, "io");
+ lua_getfield(L, -1, "stdout");
+ lua_getfield(L, -1, "write");
+ for (int i = 1; i <= n; i++) {
+ lua_pushvalue(L, -1); // write()
+ lua_pushvalue(L, -3); // io.stdout
+ luaL_tolstring(L, i, nullptr);
+ lua_pushstring(L, i != n ? "\t" : "\n");
+ lua_call(L, 3, 0);
+ }
+ return 0;
+}
+
+Lua::Lua() : m_lua_state(luaL_newstate()) {
+ assert(m_lua_state);
+ luaL_openlibs(m_lua_state);
+ luaopen_lldb(m_lua_state);
+ lua_pushcfunction(m_lua_state, lldb_print);
+ lua_setglobal(m_lua_state, "print");
+}
+
+Lua::~Lua() {
+ assert(m_lua_state);
+ lua_close(m_lua_state);
+}
+
llvm::Error Lua::Run(llvm::StringRef buffer) {
int error =
luaL_loadbuffer(m_lua_state, buffer.data(), buffer.size(), "buffer") ||
lua_pcall(m_lua_state, 0, 0, 0);
- if (!error)
+ if (error == LUA_OK)
return llvm::Error::success();
llvm::Error e = llvm::make_error<llvm::StringError>(
@@ -29,6 +79,57 @@ llvm::Error Lua::Run(llvm::StringRef buffer) {
return e;
}
+llvm::Error Lua::RegisterBreakpointCallback(void *baton, const char *body) {
+ lua_pushlightuserdata(m_lua_state, baton);
+ const char *fmt_str = "return function(frame, bp_loc, ...) {0} end";
+ std::string func_str = llvm::formatv(fmt_str, body).str();
+ if (luaL_dostring(m_lua_state, func_str.c_str()) != LUA_OK) {
+ llvm::Error e = llvm::make_error<llvm::StringError>(
+ llvm::formatv("{0}", lua_tostring(m_lua_state, -1)),
+ llvm::inconvertibleErrorCode());
+ // Pop error message from the stack.
+ lua_pop(m_lua_state, 2);
+ return e;
+ }
+ lua_settable(m_lua_state, LUA_REGISTRYINDEX);
+ return llvm::Error::success();
+}
+
+llvm::Expected<bool>
+Lua::CallBreakpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp,
+ lldb::BreakpointLocationSP bp_loc_sp,
+ StructuredData::ObjectSP extra_args_sp) {
+
+ lua_pushlightuserdata(m_lua_state, baton);
+ lua_gettable(m_lua_state, LUA_REGISTRYINDEX);
+ auto *extra_args_impl = [&]() -> StructuredDataImpl * {
+ if (extra_args_sp == nullptr)
+ return nullptr;
+ auto *extra_args_impl = new StructuredDataImpl();
+ extra_args_impl->SetObjectSP(extra_args_sp);
+ return extra_args_impl;
+ }();
+ return LLDBSwigLuaBreakpointCallbackFunction(m_lua_state, stop_frame_sp,
+ bp_loc_sp, extra_args_impl);
+}
+
+llvm::Error Lua::CheckSyntax(llvm::StringRef buffer) {
+ int error =
+ luaL_loadbuffer(m_lua_state, buffer.data(), buffer.size(), "buffer");
+ if (error == LUA_OK) {
+ // Pop buffer
+ lua_pop(m_lua_state, 1);
+ return llvm::Error::success();
+ }
+
+ llvm::Error e = llvm::make_error<llvm::StringError>(
+ llvm::formatv("{0}\n", lua_tostring(m_lua_state, -1)),
+ llvm::inconvertibleErrorCode());
+ // Pop error message from the stack.
+ lua_pop(m_lua_state, 1);
+ return e;
+}
+
llvm::Error Lua::LoadModule(llvm::StringRef filename) {
FileSpec file(filename);
if (!FileSystem::Instance().Exists(file)) {
@@ -44,7 +145,7 @@ llvm::Error Lua::LoadModule(llvm::StringRef filename) {
int error = luaL_loadfile(m_lua_state, filename.data()) ||
lua_pcall(m_lua_state, 0, 1, 0);
- if (error) {
+ if (error != LUA_OK) {
llvm::Error e = llvm::make_error<llvm::StringError>(
llvm::formatv("{0}\n", lua_tostring(m_lua_state, -1)),
llvm::inconvertibleErrorCode());
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
index 300115aac8a7..873440f0aab3 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
@@ -9,6 +9,9 @@
#ifndef liblldb_Lua_h_
#define liblldb_Lua_h_
+#include "lldb/API/SBBreakpointLocation.h"
+#include "lldb/API/SBFrame.h"
+#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/lldb-types.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
@@ -25,19 +28,17 @@ int luaopen_lldb(lua_State *L);
class Lua {
public:
- Lua() : m_lua_state(luaL_newstate()) {
- assert(m_lua_state);
- luaL_openlibs(m_lua_state);
- luaopen_lldb(m_lua_state);
- }
-
- ~Lua() {
- assert(m_lua_state);
- luaL_openlibs(m_lua_state);
- }
+ Lua();
+ ~Lua();
llvm::Error Run(llvm::StringRef buffer);
+ llvm::Error RegisterBreakpointCallback(void *baton, const char *body);
+ llvm::Expected<bool>
+ CallBreakpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp,
+ lldb::BreakpointLocationSP bp_loc_sp,
+ StructuredData::ObjectSP extra_args_sp);
llvm::Error LoadModule(llvm::StringRef filename);
+ llvm::Error CheckSyntax(llvm::StringRef buffer);
llvm::Error ChangeIO(FILE *out, FILE *err);
private:
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
index 8cbeac4563c3..920e334f51aa 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
@@ -8,29 +8,42 @@
#include "ScriptInterpreterLua.h"
#include "Lua.h"
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Target/ExecutionContext.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StringList.h"
#include "lldb/Utility/Timer.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FormatAdapters.h"
+#include <memory>
+#include <vector>
using namespace lldb;
using namespace lldb_private;
LLDB_PLUGIN_DEFINE(ScriptInterpreterLua)
+enum ActiveIOHandler {
+ eIOHandlerNone,
+ eIOHandlerBreakpoint,
+ eIOHandlerWatchpoint
+};
+
class IOHandlerLuaInterpreter : public IOHandlerDelegate,
public IOHandlerEditline {
public:
IOHandlerLuaInterpreter(Debugger &debugger,
- ScriptInterpreterLua &script_interpreter)
+ ScriptInterpreterLua &script_interpreter,
+ ActiveIOHandler active_io_handler = eIOHandlerNone)
: IOHandlerEditline(debugger, IOHandler::Type::LuaInterpreter, "lua",
">>> ", "..> ", true, debugger.GetUseColor(), 0,
*this, nullptr),
- m_script_interpreter(script_interpreter) {
+ m_script_interpreter(script_interpreter),
+ m_active_io_handler(active_io_handler) {
llvm::cantFail(m_script_interpreter.GetLua().ChangeIO(
debugger.GetOutputFile().GetStream(),
debugger.GetErrorFile().GetStream()));
@@ -41,20 +54,79 @@ public:
llvm::cantFail(m_script_interpreter.LeaveSession());
}
- void IOHandlerInputComplete(IOHandler &io_handler,
- std::string &data) override {
- if (llvm::StringRef(data).rtrim() == "quit") {
- io_handler.SetIsDone(true);
+ void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
+ const char *instructions = nullptr;
+ switch (m_active_io_handler) {
+ case eIOHandlerNone:
+ case eIOHandlerWatchpoint:
+ break;
+ case eIOHandlerBreakpoint:
+ instructions = "Enter your Lua command(s). Type 'quit' to end.\n"
+ "The commands are compiled as the body of the following "
+ "Lua function\n"
+ "function (frame, bp_loc, ...) end\n";
+ SetPrompt(llvm::StringRef("..> "));
+ break;
+ }
+ if (instructions == nullptr)
return;
+ if (interactive)
+ *io_handler.GetOutputStreamFileSP() << instructions;
+ }
+
+ bool IOHandlerIsInputComplete(IOHandler &io_handler,
+ StringList &lines) override {
+ size_t last = lines.GetSize() - 1;
+ if (IsQuitCommand(lines.GetStringAtIndex(last))) {
+ if (m_active_io_handler == eIOHandlerBreakpoint)
+ lines.DeleteStringAtIndex(last);
+ return true;
+ }
+ StreamString str;
+ lines.Join("\n", str);
+ if (llvm::Error E =
+ m_script_interpreter.GetLua().CheckSyntax(str.GetString())) {
+ std::string error_str = toString(std::move(E));
+ // Lua always errors out to incomplete code with '<eof>'
+ return error_str.find("<eof>") == std::string::npos;
}
+ // The breakpoint handler only exits with a explicit 'quit'
+ return m_active_io_handler != eIOHandlerBreakpoint;
+ }
- if (llvm::Error error = m_script_interpreter.GetLua().Run(data)) {
- *GetOutputStreamFileSP() << llvm::toString(std::move(error));
+ void IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &data) override {
+ switch (m_active_io_handler) {
+ case eIOHandlerBreakpoint: {
+ auto *bp_options_vec = static_cast<std::vector<BreakpointOptions *> *>(
+ io_handler.GetUserData());
+ for (auto *bp_options : *bp_options_vec) {
+ Status error = m_script_interpreter.SetBreakpointCommandCallback(
+ bp_options, data.c_str());
+ if (error.Fail())
+ *io_handler.GetErrorStreamFileSP() << error.AsCString() << '\n';
+ }
+ io_handler.SetIsDone(true);
+ } break;
+ case eIOHandlerWatchpoint:
+ io_handler.SetIsDone(true);
+ break;
+ case eIOHandlerNone:
+ if (IsQuitCommand(data)) {
+ io_handler.SetIsDone(true);
+ return;
+ }
+ if (llvm::Error error = m_script_interpreter.GetLua().Run(data))
+ *io_handler.GetErrorStreamFileSP() << toString(std::move(error));
+ break;
}
}
private:
ScriptInterpreterLua &m_script_interpreter;
+ ActiveIOHandler m_active_io_handler;
+
+ bool IsQuitCommand(llvm::StringRef cmd) { return cmd.rtrim() == "quit"; }
};
ScriptInterpreterLua::ScriptInterpreterLua(Debugger &debugger)
@@ -107,8 +179,7 @@ bool ScriptInterpreterLua::ExecuteOneLine(llvm::StringRef command,
}
void ScriptInterpreterLua::ExecuteInterpreterLoop() {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
// At the moment, the only time the debugger does not have an input file
// handle is when this is called directly from lua, in which case it is
@@ -124,7 +195,7 @@ void ScriptInterpreterLua::ExecuteInterpreterLoop() {
bool ScriptInterpreterLua::LoadScriptingModule(
const char *filename, bool init_session, lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp) {
+ StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) {
FileSystem::Instance().Collect(filename);
if (llvm::Error e = m_lua->LoadModule(filename)) {
@@ -174,6 +245,74 @@ llvm::Error ScriptInterpreterLua::LeaveSession() {
return m_lua->Run(str);
}
+bool ScriptInterpreterLua::BreakpointCallbackFunction(
+ void *baton, StoppointCallbackContext *context, user_id_t break_id,
+ user_id_t break_loc_id) {
+ assert(context);
+
+ ExecutionContext exe_ctx(context->exe_ctx_ref);
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target == nullptr)
+ return true;
+
+ StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
+ BreakpointSP breakpoint_sp = target->GetBreakpointByID(break_id);
+ BreakpointLocationSP bp_loc_sp(breakpoint_sp->FindLocationByID(break_loc_id));
+
+ Debugger &debugger = target->GetDebugger();
+ ScriptInterpreterLua *lua_interpreter = static_cast<ScriptInterpreterLua *>(
+ debugger.GetScriptInterpreter(true, eScriptLanguageLua));
+ Lua &lua = lua_interpreter->GetLua();
+
+ CommandDataLua *bp_option_data = static_cast<CommandDataLua *>(baton);
+ llvm::Expected<bool> BoolOrErr = lua.CallBreakpointCallback(
+ baton, stop_frame_sp, bp_loc_sp, bp_option_data->m_extra_args_sp);
+ if (llvm::Error E = BoolOrErr.takeError()) {
+ debugger.GetErrorStream() << toString(std::move(E));
+ return true;
+ }
+
+ return *BoolOrErr;
+}
+
+void ScriptInterpreterLua::CollectDataForBreakpointCommandCallback(
+ std::vector<BreakpointOptions *> &bp_options_vec,
+ CommandReturnObject &result) {
+ IOHandlerSP io_handler_sp(
+ new IOHandlerLuaInterpreter(m_debugger, *this, eIOHandlerBreakpoint));
+ io_handler_sp->SetUserData(&bp_options_vec);
+ m_debugger.RunIOHandlerAsync(io_handler_sp);
+}
+
+Status ScriptInterpreterLua::SetBreakpointCommandCallbackFunction(
+ BreakpointOptions *bp_options, const char *function_name,
+ StructuredData::ObjectSP extra_args_sp) {
+ const char *fmt_str = "return {0}(frame, bp_loc, ...)";
+ std::string oneliner = llvm::formatv(fmt_str, function_name).str();
+ return RegisterBreakpointCallback(bp_options, oneliner.c_str(),
+ extra_args_sp);
+}
+
+Status ScriptInterpreterLua::SetBreakpointCommandCallback(
+ BreakpointOptions *bp_options, const char *command_body_text) {
+ return RegisterBreakpointCallback(bp_options, command_body_text, {});
+}
+
+Status ScriptInterpreterLua::RegisterBreakpointCallback(
+ BreakpointOptions *bp_options, const char *command_body_text,
+ StructuredData::ObjectSP extra_args_sp) {
+ Status error;
+ auto data_up = std::make_unique<CommandDataLua>(extra_args_sp);
+ error = m_lua->RegisterBreakpointCallback(data_up.get(), command_body_text);
+ if (error.Fail())
+ return error;
+ auto baton_sp =
+ std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up));
+ bp_options->SetCallback(ScriptInterpreterLua::BreakpointCallbackFunction,
+ baton_sp);
+ return error;
+}
+
lldb::ScriptInterpreterSP
ScriptInterpreterLua::CreateInstance(Debugger &debugger) {
return std::make_shared<ScriptInterpreterLua>(debugger);
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
index bcc6ab24f6d0..1130ceee3c20 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
@@ -9,12 +9,27 @@
#ifndef liblldb_ScriptInterpreterLua_h_
#define liblldb_ScriptInterpreterLua_h_
+#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/lldb-enumerations.h"
namespace lldb_private {
class Lua;
class ScriptInterpreterLua : public ScriptInterpreter {
public:
+ class CommandDataLua : public BreakpointOptions::CommandData {
+ public:
+ CommandDataLua() : BreakpointOptions::CommandData() {
+ interpreter = lldb::eScriptLanguageLua;
+ }
+ CommandDataLua(StructuredData::ObjectSP extra_args_sp)
+ : BreakpointOptions::CommandData(), m_extra_args_sp(extra_args_sp) {
+ interpreter = lldb::eScriptLanguageLua;
+ }
+ StructuredData::ObjectSP m_extra_args_sp;
+ };
+
ScriptInterpreterLua(Debugger &debugger);
~ScriptInterpreterLua() override;
@@ -25,10 +40,10 @@ public:
void ExecuteInterpreterLoop() override;
- bool
- LoadScriptingModule(const char *filename, bool init_session,
- lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp = nullptr) override;
+ bool LoadScriptingModule(const char *filename, bool init_session,
+ lldb_private::Status &error,
+ StructuredData::ObjectSP *module_sp = nullptr,
+ FileSpec extra_search_dir = {}) override;
// Static Functions
static void Initialize();
@@ -41,6 +56,11 @@ public:
static const char *GetPluginDescriptionStatic();
+ static bool BreakpointCallbackFunction(void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
+
// PluginInterface protocol
lldb_private::ConstString GetPluginName() override;
@@ -51,9 +71,24 @@ public:
llvm::Error EnterSession(lldb::user_id_t debugger_id);
llvm::Error LeaveSession();
+ void CollectDataForBreakpointCommandCallback(
+ std::vector<BreakpointOptions *> &bp_options_vec,
+ CommandReturnObject &result) override;
+
+ Status SetBreakpointCommandCallback(BreakpointOptions *bp_options,
+ const char *command_body_text) override;
+
+ Status SetBreakpointCommandCallbackFunction(
+ BreakpointOptions *bp_options, const char *function_name,
+ StructuredData::ObjectSP extra_args_sp) override;
+
private:
std::unique_ptr<Lua> m_lua;
bool m_session_is_active = false;
+
+ Status RegisterBreakpointCallback(BreakpointOptions *bp_options,
+ const char *command_body_text,
+ StructuredData::ObjectSP extra_args_sp);
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index 6f040fdef09b..7c49502f1b57 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -451,7 +451,11 @@ Expected<llvm::StringRef> PythonString::AsUTF8() const {
size_t PythonString::GetSize() const {
if (IsValid()) {
#if PY_MAJOR_VERSION >= 3
+#if PY_MINOR_VERSION >= 3
+ return PyUnicode_GetLength(m_py_obj);
+#else
return PyUnicode_GetSize(m_py_obj);
+#endif
#else
return PyString_Size(m_py_obj);
#endif
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 9f56b4fa60a5..6b53bd3a2edc 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/Config.h"
+#include "lldb/lldb-enumerations.h"
#if LLDB_ENABLE_PYTHON
@@ -32,6 +33,7 @@
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Utility/ReproducerInstrumentation.h"
#include "lldb/Utility/Timer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
@@ -127,6 +129,16 @@ extern "C" unsigned int
LLDBSwigPythonCallBreakpointResolver(void *implementor, const char *method_name,
lldb_private::SymbolContext *sym_ctx);
+extern "C" void *LLDBSwigPythonCreateScriptedStopHook(
+ TargetSP target_sp, const char *python_class_name,
+ const char *session_dictionary_name, lldb_private::StructuredDataImpl *args,
+ lldb_private::Status &error);
+
+extern "C" bool
+LLDBSwigPythonStopHookCallHandleStop(void *implementor,
+ lldb::ExecutionContextRefSP exc_ctx,
+ lldb::StreamSP stream);
+
extern "C" size_t LLDBSwigPython_CalculateNumChildren(void *implementor,
uint32_t max);
@@ -204,6 +216,12 @@ extern "C" void *
LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting,
const lldb::TargetSP &target_sp);
+static ScriptInterpreterPythonImpl *GetPythonInterpreter(Debugger &debugger) {
+ ScriptInterpreter *script_interpreter =
+ debugger.GetScriptInterpreter(true, lldb::eScriptLanguagePython);
+ return static_cast<ScriptInterpreterPythonImpl *>(script_interpreter);
+}
+
static bool g_initialized = false;
namespace {
@@ -420,6 +438,7 @@ ScriptInterpreterPythonImpl::Locker::Locker(
: ScriptInterpreterLocker(),
m_teardown_session((on_leave & TearDownSession) == TearDownSession),
m_python_interpreter(py_interpreter) {
+ repro::Recorder::PrivateThread();
DoAcquireLock();
if ((on_entry & InitSession) == InitSession) {
if (!DoInitSession(on_entry, in, out, err)) {
@@ -982,8 +1001,7 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLine(
}
void ScriptInterpreterPythonImpl::ExecuteInterpreterLoop() {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
Debugger &debugger = m_debugger;
@@ -1815,11 +1833,10 @@ StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan(
return {};
Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger();
- ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
ScriptInterpreterPythonImpl *python_interpreter =
- static_cast<ScriptInterpreterPythonImpl *>(script_interpreter);
+ GetPythonInterpreter(debugger);
- if (!script_interpreter)
+ if (!python_interpreter)
return {};
void *ret_val;
@@ -1919,11 +1936,10 @@ ScriptInterpreterPythonImpl::CreateScriptedBreakpointResolver(
return StructuredData::GenericSP();
Debugger &debugger = bkpt_sp->GetTarget().GetDebugger();
- ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
ScriptInterpreterPythonImpl *python_interpreter =
- static_cast<ScriptInterpreterPythonImpl *>(script_interpreter);
+ GetPythonInterpreter(debugger);
- if (!script_interpreter)
+ if (!python_interpreter)
return StructuredData::GenericSP();
void *ret_val;
@@ -1979,6 +1995,59 @@ ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchDepth(
return lldb::eSearchDepthModule;
}
+StructuredData::GenericSP ScriptInterpreterPythonImpl::CreateScriptedStopHook(
+ TargetSP target_sp, const char *class_name, StructuredDataImpl *args_data,
+ Status &error) {
+
+ if (!target_sp) {
+ error.SetErrorString("No target for scripted stop-hook.");
+ return StructuredData::GenericSP();
+ }
+
+ if (class_name == nullptr || class_name[0] == '\0') {
+ error.SetErrorString("No class name for scripted stop-hook.");
+ return StructuredData::GenericSP();
+ }
+
+ ScriptInterpreterPythonImpl *python_interpreter =
+ GetPythonInterpreter(m_debugger);
+
+ if (!python_interpreter) {
+ error.SetErrorString("No script interpreter for scripted stop-hook.");
+ return StructuredData::GenericSP();
+ }
+
+ void *ret_val;
+
+ {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+
+ ret_val = LLDBSwigPythonCreateScriptedStopHook(
+ target_sp, class_name, python_interpreter->m_dictionary_name.c_str(),
+ args_data, error);
+ }
+
+ return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+}
+
+bool ScriptInterpreterPythonImpl::ScriptedStopHookHandleStop(
+ StructuredData::GenericSP implementor_sp, ExecutionContext &exc_ctx,
+ lldb::StreamSP stream_sp) {
+ assert(implementor_sp &&
+ "can't call a stop hook with an invalid implementor");
+ assert(stream_sp && "can't call a stop hook with an invalid stream");
+
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+
+ lldb::ExecutionContextRefSP exc_ctx_ref_sp(new ExecutionContextRef(exc_ctx));
+
+ bool ret_val = LLDBSwigPythonStopHookCallHandleStop(
+ implementor_sp->GetValue(), exc_ctx_ref_sp, stream_sp);
+ return ret_val;
+}
+
StructuredData::ObjectSP
ScriptInterpreterPythonImpl::LoadPluginModule(const FileSpec &file_spec,
lldb_private::Status &error) {
@@ -2039,11 +2108,10 @@ ScriptInterpreterPythonImpl::CreateSyntheticScriptedProvider(
return StructuredData::ObjectSP();
Debugger &debugger = target->GetDebugger();
- ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
ScriptInterpreterPythonImpl *python_interpreter =
- (ScriptInterpreterPythonImpl *)script_interpreter;
+ GetPythonInterpreter(debugger);
- if (!script_interpreter)
+ if (!python_interpreter)
return StructuredData::ObjectSP();
void *ret_val = nullptr;
@@ -2151,8 +2219,7 @@ bool ScriptInterpreterPythonImpl::GetScriptedSummary(
StructuredData::ObjectSP &callee_wrapper_sp,
const TypeSummaryOptions &options, std::string &retval) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
if (!valobj.get()) {
retval.assign("<no object>");
@@ -2210,11 +2277,10 @@ bool ScriptInterpreterPythonImpl::BreakpointCallbackFunction(
return true;
Debugger &debugger = target->GetDebugger();
- ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
ScriptInterpreterPythonImpl *python_interpreter =
- (ScriptInterpreterPythonImpl *)script_interpreter;
+ GetPythonInterpreter(debugger);
- if (!script_interpreter)
+ if (!python_interpreter)
return true;
if (python_function_name && python_function_name[0]) {
@@ -2276,11 +2342,10 @@ bool ScriptInterpreterPythonImpl::WatchpointCallbackFunction(
return true;
Debugger &debugger = target->GetDebugger();
- ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
ScriptInterpreterPythonImpl *python_interpreter =
- (ScriptInterpreterPythonImpl *)script_interpreter;
+ GetPythonInterpreter(debugger);
- if (!script_interpreter)
+ if (!python_interpreter)
return true;
if (python_function_name && python_function_name[0]) {
@@ -2669,7 +2734,10 @@ uint64_t replace_all(std::string &str, const std::string &oldStr,
bool ScriptInterpreterPythonImpl::LoadScriptingModule(
const char *pathname, bool init_session, lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp) {
+ StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) {
+ namespace fs = llvm::sys::fs;
+ namespace path = llvm::sys::path;
+
if (!pathname || !pathname[0]) {
error.SetErrorString("invalid pathname");
return false;
@@ -2677,24 +2745,55 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
- {
- FileSpec target_file(pathname);
- FileSystem::Instance().Resolve(target_file);
- FileSystem::Instance().Collect(target_file);
- std::string basename(target_file.GetFilename().GetCString());
+ // 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));
+
+ auto ExtendSysPath = [this](std::string directory) -> llvm::Error {
+ if (directory.empty()) {
+ return llvm::make_error<llvm::StringError>(
+ "invalid directory name", llvm::inconvertibleErrorCode());
+ }
+
+ replace_all(directory, "\\", "\\\\");
+ replace_all(directory, "'", "\\'");
+ // 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",
+ directory.c_str(), directory.c_str());
+ bool syspath_retval =
+ ExecuteMultipleLines(command_stream.GetData(),
+ ScriptInterpreter::ExecuteScriptOptions()
+ .SetEnableIO(false)
+ .SetSetLLDBGlobals(false))
+ .Success();
+ if (!syspath_retval) {
+ return llvm::make_error<llvm::StringError>(
+ "Python sys.path handling failed", llvm::inconvertibleErrorCode());
+ }
+
+ return llvm::Error::success();
+ };
+
+ std::string module_name(pathname);
+
+ if (extra_search_dir) {
+ if (llvm::Error e = ExtendSysPath(extra_search_dir.GetPath())) {
+ error = std::move(e);
+ return false;
+ }
+ } else {
+ FileSpec module_file(pathname);
+ FileSystem::Instance().Resolve(module_file);
+ FileSystem::Instance().Collect(module_file);
- // 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));
- namespace fs = llvm::sys::fs;
fs::file_status st;
- std::error_code ec = status(target_file.GetPath(), st);
+ std::error_code ec = status(module_file.GetPath(), st);
if (ec || st.type() == fs::file_type::status_error ||
st.type() == fs::file_type::type_unknown ||
@@ -2705,113 +2804,98 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
error.SetErrorString("invalid pathname");
return false;
}
- basename = pathname; // not a filename, probably a package of some sort,
- // let it go through
+ // Not a filename, probably a package of some sort, let it go through.
} else if (is_directory(st) || is_regular_file(st)) {
- if (target_file.GetDirectory().IsEmpty()) {
+ if (module_file.GetDirectory().IsEmpty()) {
error.SetErrorString("invalid directory name");
return false;
}
-
- 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",
- directory.c_str(), directory.c_str());
- bool syspath_retval =
- ExecuteMultipleLines(command_stream.GetData(),
- ScriptInterpreter::ExecuteScriptOptions()
- .SetEnableIO(false)
- .SetSetLLDBGlobals(false))
- .Success();
- if (!syspath_retval) {
- error.SetErrorString("Python sys.path handling failed");
+ if (llvm::Error e =
+ ExtendSysPath(module_file.GetDirectory().GetCString())) {
+ error = std::move(e);
return false;
}
-
- // strip .py or .pyc extension
- ConstString extension = target_file.GetFileNameExtension();
- if (extension) {
- if (llvm::StringRef(extension.GetCString()) == ".py")
- basename.resize(basename.length() - 3);
- else if (llvm::StringRef(extension.GetCString()) == ".pyc")
- basename.resize(basename.length() - 4);
- }
+ module_name = module_file.GetFilename().GetCString();
} else {
error.SetErrorString("no known way to import this module specification");
return false;
}
+ }
- // check if the module is already import-ed
- command_stream.Clear();
- command_stream.Printf("sys.modules.__contains__('%s')", basename.c_str());
- bool does_contain = false;
- // this call will succeed if the module was ever imported in any Debugger
- // in the lifetime of the process in which this LLDB framework is living
- bool was_imported_globally =
- (ExecuteOneLineWithReturn(
- command_stream.GetData(),
- ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain,
- ScriptInterpreter::ExecuteScriptOptions()
- .SetEnableIO(false)
- .SetSetLLDBGlobals(false)) &&
- does_contain);
- // this call will fail if the module was not imported in this Debugger
- // before
- command_stream.Clear();
- command_stream.Printf("sys.getrefcount(%s)", basename.c_str());
- bool was_imported_locally = GetSessionDictionary()
- .GetItemForKey(PythonString(basename))
- .IsAllocated();
-
- bool was_imported = (was_imported_globally || was_imported_locally);
-
- // now actually do the import
- command_stream.Clear();
-
- if (was_imported) {
- if (!was_imported_locally)
- command_stream.Printf("import %s ; reload_module(%s)", basename.c_str(),
- basename.c_str());
- else
- command_stream.Printf("reload_module(%s)", basename.c_str());
- } else
- command_stream.Printf("import %s", basename.c_str());
-
- error = ExecuteMultipleLines(command_stream.GetData(),
- ScriptInterpreter::ExecuteScriptOptions()
- .SetEnableIO(false)
- .SetSetLLDBGlobals(false));
- if (error.Fail())
- return false;
+ // Strip .py or .pyc extension
+ llvm::StringRef extension = llvm::sys::path::extension(module_name);
+ if (!extension.empty()) {
+ if (extension == ".py")
+ module_name.resize(module_name.length() - 3);
+ else if (extension == ".pyc")
+ module_name.resize(module_name.length() - 4);
+ }
- // if we are here, everything worked
- // call __lldb_init_module(debugger,dict)
- if (!LLDBSwigPythonCallModuleInit(basename.c_str(),
- m_dictionary_name.c_str(), debugger_sp)) {
- error.SetErrorString("calling __lldb_init_module failed");
- return false;
- }
+ // check if the module is already import-ed
+ StreamString command_stream;
+ command_stream.Clear();
+ command_stream.Printf("sys.modules.__contains__('%s')", module_name.c_str());
+ bool does_contain = false;
+ // this call will succeed if the module was ever imported in any Debugger
+ // in the lifetime of the process in which this LLDB framework is living
+ bool was_imported_globally =
+ (ExecuteOneLineWithReturn(
+ command_stream.GetData(),
+ ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain,
+ ScriptInterpreter::ExecuteScriptOptions()
+ .SetEnableIO(false)
+ .SetSetLLDBGlobals(false)) &&
+ does_contain);
+ // this call will fail if the module was not imported in this Debugger
+ // before
+ command_stream.Clear();
+ command_stream.Printf("sys.getrefcount(%s)", module_name.c_str());
+ bool was_imported_locally = GetSessionDictionary()
+ .GetItemForKey(PythonString(module_name))
+ .IsAllocated();
+
+ bool was_imported = (was_imported_globally || was_imported_locally);
+
+ // now actually do the import
+ command_stream.Clear();
+
+ if (was_imported) {
+ if (!was_imported_locally)
+ command_stream.Printf("import %s ; reload_module(%s)",
+ module_name.c_str(), module_name.c_str());
+ else
+ command_stream.Printf("reload_module(%s)", module_name.c_str());
+ } else
+ command_stream.Printf("import %s", module_name.c_str());
+
+ error = ExecuteMultipleLines(command_stream.GetData(),
+ ScriptInterpreter::ExecuteScriptOptions()
+ .SetEnableIO(false)
+ .SetSetLLDBGlobals(false));
+ if (error.Fail())
+ return false;
- if (module_sp) {
- // everything went just great, now set the module object
- command_stream.Clear();
- command_stream.Printf("%s", basename.c_str());
- void *module_pyobj = nullptr;
- if (ExecuteOneLineWithReturn(
- command_stream.GetData(),
- ScriptInterpreter::eScriptReturnTypeOpaqueObject,
- &module_pyobj) &&
- module_pyobj)
- *module_sp = std::make_shared<StructuredPythonObject>(module_pyobj);
- }
+ // if we are here, everything worked
+ // call __lldb_init_module(debugger,dict)
+ if (!LLDBSwigPythonCallModuleInit(module_name.c_str(),
+ m_dictionary_name.c_str(), debugger_sp)) {
+ error.SetErrorString("calling __lldb_init_module failed");
+ return false;
+ }
- return true;
+ if (module_sp) {
+ // everything went just great, now set the module object
+ command_stream.Clear();
+ command_stream.Printf("%s", module_name.c_str());
+ void *module_pyobj = nullptr;
+ if (ExecuteOneLineWithReturn(
+ command_stream.GetData(),
+ ScriptInterpreter::eScriptReturnTypeOpaqueObject, &module_pyobj) &&
+ module_pyobj)
+ *module_sp = std::make_shared<StructuredPythonObject>(module_pyobj);
}
+
+ return true;
}
bool ScriptInterpreterPythonImpl::IsReservedWord(const char *word) {
@@ -3154,8 +3238,7 @@ void ScriptInterpreterPythonImpl::InitializePrivate() {
g_initialized = true;
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
// RAII-based initialization which correctly handles multiple-initialization,
// version- specific differences among Python 2 and Python 3, and saving and
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index 22b2c8152eac..45dad4217005 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -106,6 +106,14 @@ public:
StructuredData::GenericSP implementor_sp) override;
StructuredData::GenericSP
+ CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name,
+ StructuredDataImpl *args_data, Status &error) override;
+
+ bool ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp,
+ ExecutionContext &exc_ctx,
+ lldb::StreamSP stream_sp) override;
+
+ StructuredData::GenericSP
CreateFrameRecognizer(const char *class_name) override;
lldb::ValueObjectListSP
@@ -223,10 +231,10 @@ public:
bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value,
std::string &output, Status &error) override;
- bool
- LoadScriptingModule(const char *filename, bool init_session,
- lldb_private::Status &error,
- StructuredData::ObjectSP *module_sp = nullptr) override;
+ bool LoadScriptingModule(const char *filename, bool init_session,
+ lldb_private::Status &error,
+ StructuredData::ObjectSP *module_sp = nullptr,
+ FileSpec extra_search_dir = {}) override;
bool IsReservedWord(const char *word) override;
diff --git a/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
index 5ceaf886b812..f669e5873d2d 100644
--- a/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
@@ -666,7 +666,7 @@ private:
// regex {search-regex}
// Parse action.
- auto action_end_pos = rule_text.find(" ");
+ auto action_end_pos = rule_text.find(' ');
if (action_end_pos == std::string::npos) {
error.SetErrorStringWithFormat("could not parse filter rule "
"action from \"%s\"",
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
index eeec7296747e..07e5b284eab8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -326,7 +326,8 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
}
const SectionList &list = *module.GetSectionList();
- llvm::DenseMap<addr_t, Symbol> symbols;
+ llvm::DenseSet<addr_t> found_symbol_addresses;
+ std::vector<Symbol> symbols;
auto add_symbol = [&](addr_t address, llvm::Optional<addr_t> size,
llvm::StringRef name) {
address += base;
@@ -338,8 +339,12 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
name, address);
return;
}
- symbols.try_emplace(
- address, /*symID*/ 0, Mangled(name), eSymbolTypeCode,
+ // Keep track of what addresses were already added so far and only add
+ // the symbol with the first address.
+ if (!found_symbol_addresses.insert(address).second)
+ return;
+ symbols.emplace_back(
+ /*symID*/ 0, Mangled(name), eSymbolTypeCode,
/*is_global*/ true, /*is_debug*/ false,
/*is_trampoline*/ false, /*is_artificial*/ false,
AddressRange(section_sp, address - section_sp->GetFileAddress(),
@@ -359,8 +364,8 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
LLDB_LOG(log, "Failed to parse: {0}. Skipping record.", line);
}
- for (auto &KV : symbols)
- symtab.AddSymbol(std::move(KV.second));
+ for (Symbol &symbol : symbols)
+ symtab.AddSymbol(std::move(symbol));
symtab.CalculateSymbolSizes();
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
index 33ab11a3ca40..60b6b726f6c0 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
@@ -42,8 +42,8 @@ std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create(
if (!apple_objc_table_up->IsValid())
apple_objc_table_up.reset();
- if (apple_names_table_up || apple_names_table_up || apple_types_table_up ||
- apple_objc_table_up)
+ if (apple_names_table_up || apple_namespaces_table_up ||
+ apple_types_table_up || apple_objc_table_up)
return std::make_unique<AppleDWARFIndex>(
module, std::move(apple_names_table_up),
std::move(apple_namespaces_table_up), std::move(apple_types_table_up),
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 2d1db66e7fd9..188a667ca564 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -209,11 +209,12 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
GetClangASTImporter().RequireCompleteType(ClangUtil::GetQualType(type));
SymbolFileDWARF *dwarf = die.GetDWARF();
- TypeSP type_sp(new Type(
- die.GetID(), dwarf, pcm_type_sp->GetName(), pcm_type_sp->GetByteSize(),
- nullptr, LLDB_INVALID_UID, Type::eEncodingInvalid,
- &pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward,
- TypePayloadClang(GetOwningClangModule(die))));
+ TypeSP type_sp(new Type(die.GetID(), dwarf, pcm_type_sp->GetName(),
+ pcm_type_sp->GetByteSize(nullptr), nullptr,
+ LLDB_INVALID_UID, Type::eEncodingInvalid,
+ &pcm_type_sp->GetDeclaration(), type,
+ Type::ResolveState::Forward,
+ TypePayloadClang(GetOwningClangModule(die))));
dwarf->GetTypeList().Insert(type_sp);
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
@@ -229,31 +230,73 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
return type_sp;
}
-static void CompleteExternalTagDeclType(TypeSystemClang &ast,
- ClangASTImporter &ast_importer,
- clang::DeclContext *decl_ctx,
- DWARFDIE die,
- const char *type_name_cstr) {
+static void ForcefullyCompleteType(CompilerType type) {
+ bool started = TypeSystemClang::StartTagDeclarationDefinition(type);
+ lldbassert(started && "Unable to start a class type definition.");
+ TypeSystemClang::CompleteTagDeclarationDefinition(type);
+ const clang::TagDecl *td = ClangUtil::GetAsTagDecl(type);
+ auto &ts = llvm::cast<TypeSystemClang>(*type.GetTypeSystem());
+ ts.GetMetadata(td)->SetIsForcefullyCompleted();
+}
+
+/// Complete a type from debug info, or mark it as forcefully completed if
+/// there is no definition of the type in the current Module. Call this function
+/// in contexts where the usual C++ rules require a type to be complete (base
+/// class, member, etc.).
+static void RequireCompleteType(CompilerType type) {
+ // Technically, enums can be incomplete too, but we don't handle those as they
+ // are emitted even under -flimit-debug-info.
+ if (!TypeSystemClang::IsCXXClassType(type))
+ return;
+
+ if (type.GetCompleteType())
+ return;
+
+ // No complete definition in this module. Mark the class as complete to
+ // satisfy local ast invariants, but make a note of the fact that
+ // it is not _really_ complete so we can later search for a definition in a
+ // different module.
+ // Since we provide layout assistance, layouts of types containing this class
+ // will be correct even if we are not able to find the definition elsewhere.
+ ForcefullyCompleteType(type);
+}
+
+/// This function serves a similar purpose as RequireCompleteType above, but it
+/// avoids completing the type if it is not immediately necessary. It only
+/// ensures we _can_ complete the type later.
+static void PrepareContextToReceiveMembers(TypeSystemClang &ast,
+ ClangASTImporter &ast_importer,
+ clang::DeclContext *decl_ctx,
+ DWARFDIE die,
+ const char *type_name_cstr) {
auto *tag_decl_ctx = clang::dyn_cast<clang::TagDecl>(decl_ctx);
if (!tag_decl_ctx)
+ return; // Non-tag context are always ready.
+
+ // We have already completed the type, or we have found its definition and are
+ // ready to complete it later (cf. ParseStructureLikeDIE).
+ if (tag_decl_ctx->isCompleteDefinition() || tag_decl_ctx->isBeingDefined())
return;
+ // We reach this point of the tag was present in the debug info as a
+ // declaration only. If it was imported from another AST context (in the
+ // gmodules case), we can complete the type by doing a full import.
+
// If this type was not imported from an external AST, there's nothing to do.
CompilerType type = ast.GetTypeForDecl(tag_decl_ctx);
- if (!type || !ast_importer.CanImport(type))
- return;
-
- auto qual_type = ClangUtil::GetQualType(type);
- if (!ast_importer.RequireCompleteType(qual_type)) {
+ if (type && ast_importer.CanImport(type)) {
+ auto qual_type = ClangUtil::GetQualType(type);
+ if (ast_importer.RequireCompleteType(qual_type))
+ return;
die.GetDWARF()->GetObjectFile()->GetModule()->ReportError(
"Unable to complete the Decl context for DIE '%s' at offset "
"0x%8.8x.\nPlease file a bug report.",
type_name_cstr ? type_name_cstr : "", die.GetOffset());
- // We need to make the type look complete otherwise, we might crash in
- // Clang when adding children.
- if (TypeSystemClang::StartTagDeclarationDefinition(type))
- TypeSystemClang::CompleteTagDeclarationDefinition(type);
}
+
+ // We don't have a type definition and/or the import failed. We must
+ // forcefully complete the type to avoid crashes.
+ ForcefullyCompleteType(type);
}
ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) {
@@ -298,7 +341,9 @@ ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) {
break;
case DW_AT_decl_file:
- decl.SetFile(die.GetCU()->GetFile(form_value.Unsigned()));
+ // die.GetCU() can differ if DW_AT_specification uses DW_FORM_ref_addr.
+ decl.SetFile(
+ attributes.CompileUnitAtIndex(i)->GetFile(form_value.Unsigned()));
break;
case DW_AT_decl_line:
decl.SetLine(form_value.Unsigned());
@@ -513,42 +558,51 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
TypeSP type_sp;
CompilerType clang_type;
- if (tag == DW_TAG_typedef && attrs.type.IsValid()) {
- // Try to parse a typedef from the (DWARF embedded in the) Clang
- // module 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 Clang modules
- // if possible.
- //
- // The type_sp returned will be empty if the typedef doesn't
- // exist in a module 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 debug info, so we make
- // sure we don't get into this situation by always resolving
- // typedefs from the module.
- const DWARFDIE encoding_die = attrs.type.Reference();
-
- // 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 = ParseTypeFromClangModule(sc, die, log);
- if (type_sp)
- return type_sp;
+ if (tag == DW_TAG_typedef) {
+ // DeclContext will be populated when the clang type is materialized in
+ // Type::ResolveCompilerType.
+ PrepareContextToReceiveMembers(
+ m_ast, GetClangASTImporter(),
+ GetClangDeclContextContainingDIE(die, nullptr), die,
+ attrs.name.GetCString());
+
+ if (attrs.type.IsValid()) {
+ // Try to parse a typedef from the (DWARF embedded in the) Clang
+ // module 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 Clang modules
+ // if possible.
+ //
+ // The type_sp returned will be empty if the typedef doesn't
+ // exist in a module 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 debug info, so we make
+ // sure we don't get into this situation by always resolving
+ // typedefs from the module.
+ const DWARFDIE encoding_die = attrs.type.Reference();
+
+ // 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 = ParseTypeFromClangModule(sc, die, log);
+ if (type_sp)
+ return type_sp;
+ }
}
}
@@ -810,7 +864,7 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc,
bool is_signed = false;
enumerator_clang_type.IsIntegerType(is_signed);
ParseChildEnumerators(clang_type, is_signed,
- type_sp->GetByteSize().getValueOr(0), die);
+ type_sp->GetByteSize(nullptr).getValueOr(0), die);
}
TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);
} else {
@@ -1172,7 +1226,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
}
if (!function_decl) {
- const char *name = attrs.name.GetCString();
+ llvm::StringRef name = attrs.name.GetStringRef();
// We currently generate function templates with template parameters in
// their name. In order to get closer to the AST that clang generates
@@ -1196,12 +1250,12 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
template_function_decl = m_ast.CreateFunctionDeclaration(
ignore_containing_context ? m_ast.GetTranslationUnitDecl()
: containing_decl_ctx,
- GetOwningClangModule(die), attrs.name.GetCString(), clang_type,
+ GetOwningClangModule(die), attrs.name.GetStringRef(), clang_type,
attrs.storage, attrs.is_inline);
clang::FunctionTemplateDecl *func_template_decl =
m_ast.CreateFunctionTemplateDecl(
containing_decl_ctx, GetOwningClangModule(die),
- template_function_decl, name, template_param_infos);
+ template_function_decl, template_param_infos);
m_ast.CreateFunctionTemplateSpecializationInfo(
template_function_decl, func_template_decl, template_param_infos);
}
@@ -1261,9 +1315,9 @@ TypeSP DWARFASTParserClang::ParseArrayType(const DWARFDIE &die,
attrs.bit_stride = array_info->bit_stride;
}
if (attrs.byte_stride == 0 && attrs.bit_stride == 0)
- attrs.byte_stride = element_type->GetByteSize().getValueOr(0);
+ attrs.byte_stride = element_type->GetByteSize(nullptr).getValueOr(0);
CompilerType array_element_type = element_type->GetForwardCompilerType();
- CompleteType(array_element_type);
+ RequireCompleteType(array_element_type);
uint64_t array_element_bit_stride =
attrs.byte_stride * 8 + attrs.bit_stride;
@@ -1318,28 +1372,6 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType(
return nullptr;
}
-void DWARFASTParserClang::CompleteType(CompilerType type) {
- // Technically, enums can be incomplete too, but we don't handle those as they
- // are emitted even under -flimit-debug-info.
- if (!TypeSystemClang::IsCXXClassType(type))
- return;
-
- if (type.GetCompleteType())
- return;
-
- // No complete definition in this module. Mark the class as complete to
- // satisfy local ast invariants, but make a note of the fact that
- // it is not _really_ complete so we can later search for a definition in a
- // different module.
- // Since we provide layout assistance, layouts of types containing this class
- // will be correct even if we are not able to find the definition elsewhere.
- bool started = TypeSystemClang::StartTagDeclarationDefinition(type);
- lldbassert(started && "Unable to start a class type definition.");
- TypeSystemClang::CompleteTagDeclarationDefinition(type);
- const clang::TagDecl *td = ClangUtil::GetAsTagDecl(type);
- m_ast.GetMetadata(td)->SetIsForcefullyCompleted();
-}
-
TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType(
const SymbolContext &sc, const DWARFDIE &die, TypeSP type_sp) {
if (!type_sp)
@@ -1559,13 +1591,8 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
clang::DeclContext *decl_ctx =
GetClangDeclContextContainingDIE(die, nullptr);
- // If your decl context is a record that was imported from another
- // AST context (in the gmodules case), we need to make sure the type
- // backing the Decl is complete before adding children to it. This is
- // not an issue in the non-gmodules case because the debug info will
- // always contain a full definition of parent types in that case.
- CompleteExternalTagDeclType(m_ast, GetClangASTImporter(), decl_ctx, die,
- attrs.name.GetCString());
+ PrepareContextToReceiveMembers(m_ast, GetClangASTImporter(), decl_ctx, die,
+ attrs.name.GetCString());
if (attrs.accessibility == eAccessNone && decl_ctx) {
// Check the decl context that contains this class/struct/union. If
@@ -1640,33 +1667,6 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
*unique_ast_entry_up);
- if (attrs.is_forward_declaration && die.HasChildren()) {
- // Check to see if the DIE actually has a definition, some version of
- // GCC will
- // emit DIEs with DW_AT_declaration set to true, but yet still have
- // subprogram, members, or inheritance, so we can't trust it
- DWARFDIE child_die = die.GetFirstChild();
- while (child_die) {
- switch (child_die.Tag()) {
- case DW_TAG_inheritance:
- case DW_TAG_subprogram:
- case DW_TAG_member:
- case DW_TAG_APPLE_property:
- case DW_TAG_class_type:
- case DW_TAG_structure_type:
- case DW_TAG_enumeration_type:
- case DW_TAG_typedef:
- case DW_TAG_union_type:
- child_die.Clear();
- attrs.is_forward_declaration = false;
- break;
- default:
- child_die = child_die.GetSibling();
- break;
- }
- }
- }
-
if (!attrs.is_forward_declaration) {
// Always start the definition for a class type so that if the class
// has child classes or types that require the class to be created
@@ -1944,8 +1944,6 @@ bool DWARFASTParserClang::ParseTemplateParameterInfos(
break;
}
}
- if (template_param_infos.args.empty())
- return false;
return template_param_infos.args.size() == template_param_infos.names.size();
}
@@ -2042,7 +2040,7 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
clang::TypeSourceInfo *type_source_info =
base_class->getTypeSourceInfo();
if (type_source_info)
- CompleteType(m_ast.GetType(type_source_info->getType()));
+ RequireCompleteType(m_ast.GetType(type_source_info->getType()));
}
m_ast.TransferBaseClasses(clang_type.GetOpaqueQualType(),
@@ -2057,7 +2055,7 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
if (!layout_info.field_offsets.empty() || !layout_info.base_offsets.empty() ||
!layout_info.vbase_offsets.empty()) {
if (type)
- layout_info.bit_size = type->GetByteSize().getValueOr(0) * 8;
+ layout_info.bit_size = type->GetByteSize(nullptr).getValueOr(0) * 8;
if (layout_info.bit_size == 0)
layout_info.bit_size =
die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
@@ -2079,7 +2077,7 @@ bool DWARFASTParserClang::CompleteEnumType(const DWARFDIE &die,
bool is_signed = false;
clang_type.IsIntegerType(is_signed);
ParseChildEnumerators(clang_type, is_signed,
- type->GetByteSize().getValueOr(0), die);
+ type->GetByteSize(nullptr).getValueOr(0), die);
}
TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);
}
@@ -2567,7 +2565,7 @@ void DWARFASTParserClang::ParseSingleMember(
this_field_info.bit_offset = data_bit_offset;
} else {
if (!byte_size)
- byte_size = member_type->GetByteSize();
+ byte_size = member_type->GetByteSize(nullptr);
ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
if (objfile->GetByteOrder() == eByteOrderLittle) {
@@ -2578,10 +2576,18 @@ void DWARFASTParserClang::ParseSingleMember(
}
}
- if ((this_field_info.bit_offset >= parent_bit_size) ||
- (last_field_info.IsBitfield() &&
- !last_field_info.NextBitfieldOffsetIsValid(
- this_field_info.bit_offset))) {
+ // The ObjC runtime knows the byte offset but we still need to provide
+ // the bit-offset in the layout. It just means something different then
+ // what it does in C and C++. So we skip this check for ObjC types.
+ //
+ // We also skip this for fields of a union since they will all have a
+ // zero offset.
+ if (!TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type) &&
+ !(parent_die.Tag() == DW_TAG_union_type && this_field_info.bit_offset == 0) &&
+ ((this_field_info.bit_offset >= parent_bit_size) ||
+ (last_field_info.IsBitfield() &&
+ !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 "
@@ -2707,7 +2713,7 @@ void DWARFASTParserClang::ParseSingleMember(
}
}
- CompleteType(member_clang_type);
+ RequireCompleteType(member_clang_type);
field_decl = TypeSystemClang::AddFieldToRecordType(
class_clang_type, name, member_clang_type, accessibility,
@@ -3043,88 +3049,85 @@ DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
die = die.GetSibling()) {
const dw_tag_t tag = die.Tag();
- switch (tag) {
- case DW_TAG_subrange_type: {
- DWARFAttributes attributes;
- const size_t num_child_attributes = die.GetAttributes(attributes);
- if (num_child_attributes > 0) {
- uint64_t num_elements = 0;
- uint64_t lower_bound = 0;
- uint64_t upper_bound = 0;
- bool upper_bound_valid = false;
- uint32_t i;
- for (i = 0; i < num_child_attributes; ++i) {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_name:
- break;
+ if (tag != DW_TAG_subrange_type)
+ continue;
- case DW_AT_count:
- if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) {
- if (var_die.Tag() == DW_TAG_variable)
- if (exe_ctx) {
- if (auto frame = exe_ctx->GetFrameSP()) {
- Status error;
- lldb::VariableSP var_sp;
- auto valobj_sp = frame->GetValueForVariableExpressionPath(
- var_die.GetName(), eNoDynamicValues, 0, var_sp,
- error);
- if (valobj_sp) {
- num_elements = valobj_sp->GetValueAsUnsigned(0);
- break;
- }
+ DWARFAttributes attributes;
+ const size_t num_child_attributes = die.GetAttributes(attributes);
+ if (num_child_attributes > 0) {
+ uint64_t num_elements = 0;
+ uint64_t lower_bound = 0;
+ uint64_t upper_bound = 0;
+ bool upper_bound_valid = false;
+ uint32_t i;
+ for (i = 0; i < num_child_attributes; ++i) {
+ const dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+ if (attributes.ExtractFormValueAtIndex(i, form_value)) {
+ switch (attr) {
+ case DW_AT_name:
+ break;
+
+ case DW_AT_count:
+ if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) {
+ if (var_die.Tag() == DW_TAG_variable)
+ if (exe_ctx) {
+ if (auto frame = exe_ctx->GetFrameSP()) {
+ Status error;
+ lldb::VariableSP var_sp;
+ auto valobj_sp = frame->GetValueForVariableExpressionPath(
+ var_die.GetName(), eNoDynamicValues, 0, var_sp,
+ error);
+ if (valobj_sp) {
+ num_elements = valobj_sp->GetValueAsUnsigned(0);
+ break;
}
}
- } else
- num_elements = form_value.Unsigned();
- break;
+ }
+ } else
+ num_elements = form_value.Unsigned();
+ break;
- case DW_AT_bit_stride:
- array_info.bit_stride = form_value.Unsigned();
- break;
+ case DW_AT_bit_stride:
+ array_info.bit_stride = form_value.Unsigned();
+ break;
- case DW_AT_byte_stride:
- array_info.byte_stride = form_value.Unsigned();
- break;
+ case DW_AT_byte_stride:
+ array_info.byte_stride = form_value.Unsigned();
+ break;
- case DW_AT_lower_bound:
- lower_bound = form_value.Unsigned();
- break;
+ case DW_AT_lower_bound:
+ lower_bound = form_value.Unsigned();
+ break;
- case DW_AT_upper_bound:
- upper_bound_valid = true;
- upper_bound = form_value.Unsigned();
- break;
+ case DW_AT_upper_bound:
+ upper_bound_valid = true;
+ upper_bound = form_value.Unsigned();
+ break;
- default:
- case DW_AT_abstract_origin:
- case DW_AT_accessibility:
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_data_location:
- case DW_AT_declaration:
- case DW_AT_description:
- case DW_AT_sibling:
- case DW_AT_threads_scaled:
- case DW_AT_type:
- case DW_AT_visibility:
- break;
- }
+ default:
+ case DW_AT_abstract_origin:
+ case DW_AT_accessibility:
+ case DW_AT_allocated:
+ case DW_AT_associated:
+ case DW_AT_data_location:
+ case DW_AT_declaration:
+ case DW_AT_description:
+ case DW_AT_sibling:
+ case DW_AT_threads_scaled:
+ case DW_AT_type:
+ case DW_AT_visibility:
+ break;
}
}
+ }
- if (num_elements == 0) {
- if (upper_bound_valid && upper_bound >= lower_bound)
- num_elements = upper_bound - lower_bound + 1;
- }
-
- array_info.element_orders.push_back(num_elements);
+ if (num_elements == 0) {
+ if (upper_bound_valid && upper_bound >= lower_bound)
+ num_elements = upper_bound - lower_bound + 1;
}
- } break;
- default:
- break;
+
+ array_info.element_orders.push_back(num_elements);
}
}
return array_info;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 2ef49abc1da1..e13716b95c1c 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -217,12 +217,6 @@ private:
ParsedDWARFTypeAttributes &attrs);
lldb::TypeSP ParsePointerToMemberType(const DWARFDIE &die,
const ParsedDWARFTypeAttributes &attrs);
-
- /// Complete a type from debug info, or mark it as forcefully completed if
- /// there is no of the type in the current Module. Call this function in
- /// contexts where the usual C++ rules require a type to be complete (base
- /// class, member, etc.).
- void CompleteType(lldb_private::CompilerType type);
};
/// Parsed form of all attributes that are relevant for type reconstruction.
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
index 6c72d9e26221..ef98d7e33a90 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
@@ -25,7 +25,7 @@ uint32_t DWARFAttributes::FindAttributeIndex(dw_attr_t attr) const {
return UINT32_MAX;
}
-void DWARFAttributes::Append(const DWARFUnit *cu, dw_offset_t attr_die_offset,
+void DWARFAttributes::Append(DWARFUnit *cu, dw_offset_t attr_die_offset,
dw_attr_t attr, dw_form_t form) {
AttributeValue attr_value = {
cu, attr_die_offset, {attr, form, DWARFFormValue::ValueType()}};
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
index 9948969f108f..8c21404610d7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
@@ -52,11 +52,9 @@ public:
DWARFAttributes();
~DWARFAttributes();
- void Append(const DWARFUnit *cu, dw_offset_t attr_die_offset,
- dw_attr_t attr, dw_form_t form);
- const DWARFUnit *CompileUnitAtIndex(uint32_t i) const {
- return m_infos[i].cu;
- }
+ void Append(DWARFUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr,
+ dw_form_t form);
+ DWARFUnit *CompileUnitAtIndex(uint32_t i) const { return m_infos[i].cu; }
dw_offset_t DIEOffsetAtIndex(uint32_t i) const {
return m_infos[i].die_offset;
}
@@ -73,8 +71,8 @@ public:
protected:
struct AttributeValue {
- const DWARFUnit *cu; // Keep the compile unit with each attribute in
- // case we have DW_FORM_ref_addr values
+ DWARFUnit *cu; // Keep the compile unit with each attribute in
+ // case we have DW_FORM_ref_addr values
dw_offset_t die_offset;
DWARFAttribute attr;
};
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
index f54fe0662aa2..9ca160b474fc 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -99,3 +99,18 @@ void DWARFCompileUnit::BuildAddressRangeTable(
}
}
}
+
+DWARFCompileUnit &DWARFCompileUnit::GetNonSkeletonUnit() {
+ return llvm::cast<DWARFCompileUnit>(DWARFUnit::GetNonSkeletonUnit());
+}
+
+DWARFDIE DWARFCompileUnit::LookupAddress(const dw_addr_t address) {
+ if (DIE()) {
+ const DWARFDebugAranges &func_aranges = GetFunctionAranges();
+
+ // Re-check the aranges auto pointer contents in case it was created above
+ if (!func_aranges.IsEmpty())
+ return GetDIE(func_aranges.FindAddress(address));
+ }
+ return DWARFDIE();
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
index 3ec161f7dd51..ab3017ba0ffc 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -20,6 +20,10 @@ public:
static bool classof(const DWARFUnit *unit) { return !unit->IsTypeUnit(); }
+ DWARFCompileUnit &GetNonSkeletonUnit();
+
+ DWARFDIE LookupAddress(const dw_addr_t address);
+
private:
DWARFCompileUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
const DWARFUnitHeader &header,
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
index 7dc52c1e2df0..9f190fbcee87 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
@@ -39,7 +39,7 @@ DWARFDebugAranges::extract(const DWARFDataExtractor &debug_aranges_data) {
Range range;
while (debug_aranges_data.ValidOffset(offset)) {
llvm::Error error = set.extract(debug_aranges_data, &offset);
- if (!error)
+ if (error)
return error;
const uint32_t num_descriptors = set.NumDescriptors();
@@ -78,8 +78,7 @@ void DWARFDebugAranges::AppendRange(dw_offset_t offset, dw_addr_t low_pc,
}
void DWARFDebugAranges::Sort(bool minimize) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
+ LLDB_SCOPED_TIMERF("%s this = %p", LLVM_PRETTY_FUNCTION,
static_cast<void *>(this));
m_aranges.Sort();
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index 874978bf1398..8d393b295443 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -199,4 +199,3 @@ DWARFDebugInfo::GetDIE(const DIERef &die_ref) {
return cu->GetNonSkeletonUnit().GetDIE(die_ref.die_offset());
return DWARFDIE(); // Not found
}
-
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index f6425a889da8..421298802645 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -399,7 +399,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
// specification or abstract origin attributes and including those in the
// results. Any duplicate attributes will have the first instance take
// precedence (this can happen for declaration attributes).
-size_t DWARFDebugInfoEntry::GetAttributes(const DWARFUnit *cu,
+size_t DWARFDebugInfoEntry::GetAttributes(DWARFUnit *cu,
DWARFAttributes &attributes,
Recurse recurse,
uint32_t curr_depth) const {
@@ -687,13 +687,15 @@ const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const {
/// table, except that the actual DIE offset for the function is placed in the
/// table instead of the compile unit offset.
void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
- const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const {
+ DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const {
if (m_tag) {
if (m_tag == DW_TAG_subprogram) {
- dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
- dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
- if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) {
- debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc);
+ DWARFRangeList ranges;
+ GetAttributeAddressRanges(cu, ranges,
+ /*check_hi_lo_pc=*/true);
+ for (const auto &r : ranges) {
+ debug_aranges->AppendRange(GetOffset(), r.GetRangeBase(),
+ r.GetRangeEnd());
}
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 3019e1767f18..0ba56a0a4161 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -42,14 +42,14 @@ public:
bool operator==(const DWARFDebugInfoEntry &rhs) const;
bool operator!=(const DWARFDebugInfoEntry &rhs) const;
- void BuildFunctionAddressRangeTable(const DWARFUnit *cu,
+ void BuildFunctionAddressRangeTable(DWARFUnit *cu,
DWARFDebugAranges *debug_aranges) const;
bool Extract(const lldb_private::DWARFDataExtractor &data,
const DWARFUnit *cu, lldb::offset_t *offset_ptr);
using Recurse = DWARFBaseDIE::Recurse;
- size_t GetAttributes(const DWARFUnit *cu, DWARFAttributes &attrs,
+ size_t GetAttributes(DWARFUnit *cu, DWARFAttributes &attrs,
Recurse recurse = Recurse::yes) const {
return GetAttributes(cu, attrs, recurse, 0 /* curr_depth */);
}
@@ -180,8 +180,8 @@ protected:
dw_tag_t m_tag = llvm::dwarf::DW_TAG_null;
private:
- size_t GetAttributes(const DWARFUnit *cu, DWARFAttributes &attrs,
- Recurse recurse, uint32_t curr_depth) const;
+ size_t GetAttributes(DWARFUnit *cu, DWARFAttributes &attrs, Recurse recurse,
+ uint32_t curr_depth) const;
};
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
index b401352c693d..fe6a55520978 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -42,6 +42,7 @@ public:
DWARFFormValue(const DWARFUnit *unit) : m_unit(unit) {}
DWARFFormValue(const DWARFUnit *unit, dw_form_t form)
: m_unit(unit), m_form(form) {}
+ const DWARFUnit *GetUnit() const { return m_unit; }
void SetUnit(const DWARFUnit *unit) { m_unit = unit; }
dw_form_t Form() const { return m_form; }
dw_form_t& FormRef() { return m_form; }
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index dfa40759a7ff..a761dd3daac4 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -34,7 +34,8 @@ DWARFUnit::DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
const DWARFAbbreviationDeclarationSet &abbrevs,
DIERef::Section section, bool is_dwo)
: UserID(uid), m_dwarf(dwarf), m_header(header), m_abbrevs(&abbrevs),
- m_cancel_scopes(false), m_section(section), m_is_dwo(is_dwo) {}
+ m_cancel_scopes(false), m_section(section), m_is_dwo(is_dwo),
+ m_dwo_id(header.GetDWOId()) {}
DWARFUnit::~DWARFUnit() = default;
@@ -49,9 +50,7 @@ void DWARFUnit::ExtractUnitDIEIfNeeded() {
if (m_first_die)
return; // Already parsed
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%8.8x: DWARFUnit::ExtractUnitDIEIfNeeded()",
- GetOffset());
+ LLDB_SCOPED_TIMERF("%8.8x: DWARFUnit::ExtractUnitDIEIfNeeded()", GetOffset());
// Set the offset to that of the first DIE and calculate the start of the
// next compilation unit header.
@@ -145,9 +144,7 @@ DWARFUnit::ScopedExtractDIEs &DWARFUnit::ScopedExtractDIEs::operator=(
void DWARFUnit::ExtractDIEsRWLocked() {
llvm::sys::ScopedWriter first_die_lock(m_first_die_mutex);
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%8.8x: DWARFUnit::ExtractDIEsIfNeeded()",
- GetOffset());
+ LLDB_SCOPED_TIMERF("%8.8x: DWARFUnit::ExtractDIEsIfNeeded()", GetOffset());
// Set the offset to that of the first DIE and calculate the start of the
// next compilation unit header.
@@ -288,6 +285,11 @@ void DWARFUnit::SetDwoStrOffsetsBase() {
SetStrOffsetsBase(baseOffset);
}
+uint64_t DWARFUnit::GetDWOId() {
+ ExtractUnitDIEIfNeeded();
+ return m_dwo_id;
+}
+
// m_die_array_mutex must be already held as read/write.
void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
llvm::Optional<uint64_t> addr_base, gnu_addr_base, ranges_base,
@@ -341,6 +343,9 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
case DW_AT_GNU_ranges_base:
gnu_ranges_base = form_value.Unsigned();
break;
+ case DW_AT_GNU_dwo_id:
+ m_dwo_id = form_value.Unsigned();
+ break;
}
}
@@ -354,9 +359,8 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
if (!dwo_symbol_file)
return;
- uint64_t main_dwo_id =
- cu_die.GetAttributeValueAsUnsigned(this, DW_AT_GNU_dwo_id, 0);
- DWARFUnit *dwo_cu = dwo_symbol_file->GetDWOCompileUnitForHash(main_dwo_id);
+ DWARFUnit *dwo_cu = dwo_symbol_file->GetDWOCompileUnitForHash(m_dwo_id);
+
if (!dwo_cu)
return; // Can't fetch the compile unit from the dwo file.
dwo_cu->SetUserData(this);
@@ -392,17 +396,6 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
m_dwo = std::shared_ptr<DWARFUnit>(std::move(dwo_symbol_file), dwo_cu);
}
-DWARFDIE DWARFUnit::LookupAddress(const dw_addr_t address) {
- if (DIE()) {
- const DWARFDebugAranges &func_aranges = GetFunctionAranges();
-
- // Re-check the aranges auto pointer contents in case it was created above
- if (!func_aranges.IsEmpty())
- return GetDIE(func_aranges.FindAddress(address));
- }
- return DWARFDIE();
-}
-
size_t DWARFUnit::GetDebugInfoSize() const {
return GetLengthByteSize() + GetLength() - GetHeaderByteSize();
}
@@ -536,21 +529,23 @@ static bool CompareDIEOffset(const DWARFDebugInfoEntry &die,
// DIE from this compile unit. Otherwise we grab the DIE from the DWARF file.
DWARFDIE
DWARFUnit::GetDIE(dw_offset_t die_offset) {
- if (die_offset != DW_INVALID_OFFSET) {
- if (ContainsDIEOffset(die_offset)) {
- ExtractDIEsIfNeeded();
- DWARFDebugInfoEntry::const_iterator end = m_die_array.cend();
- DWARFDebugInfoEntry::const_iterator pos =
- lower_bound(m_die_array.cbegin(), end, die_offset, CompareDIEOffset);
- if (pos != end) {
- if (die_offset == (*pos).GetOffset())
- return DWARFDIE(this, &(*pos));
- }
- } else
- GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
- "GetDIE for DIE 0x%" PRIx32 " is outside of its CU 0x%" PRIx32,
- die_offset, GetOffset());
+ if (die_offset == DW_INVALID_OFFSET)
+ return DWARFDIE(); // Not found
+
+ if (!ContainsDIEOffset(die_offset)) {
+ GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
+ "GetDIE for DIE 0x%" PRIx32 " is outside of its CU 0x%" PRIx32,
+ die_offset, GetOffset());
+ return DWARFDIE(); // Not found
}
+
+ ExtractDIEsIfNeeded();
+ DWARFDebugInfoEntry::const_iterator end = m_die_array.cend();
+ DWARFDebugInfoEntry::const_iterator pos =
+ lower_bound(m_die_array.cbegin(), end, die_offset, CompareDIEOffset);
+
+ if (pos != end && die_offset == (*pos).GetOffset())
+ return DWARFDIE(this, &(*pos));
return DWARFDIE(); // Not found
}
@@ -801,7 +796,8 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data,
header.m_unit_type = data.GetU8(offset_ptr);
header.m_addr_size = data.GetU8(offset_ptr);
header.m_abbr_offset = data.GetDWARFOffset(offset_ptr);
- if (header.m_unit_type == llvm::dwarf::DW_UT_skeleton)
+ if (header.m_unit_type == llvm::dwarf::DW_UT_skeleton ||
+ header.m_unit_type == llvm::dwarf::DW_UT_split_compile)
header.m_dwo_id = data.GetU64(offset_ptr);
} else {
header.m_abbr_offset = data.GetDWARFOffset(offset_ptr);
@@ -946,7 +942,7 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) {
llvm::Expected<llvm::DWARFAddressRangesVector> llvm_ranges =
range_list_or_error->getAbsoluteRanges(
llvm::object::SectionedAddress{GetBaseAddress()},
- [&](uint32_t index) {
+ GetAddressByteSize(), [&](uint32_t index) {
uint32_t index_size = GetAddressByteSize();
dw_offset_t addr_base = GetAddrBase();
lldb::offset_t offset = addr_base + index * index_size;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index affad286a490..5739c36bbacb 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -65,6 +65,7 @@ public:
}
uint64_t GetTypeHash() const { return m_type_hash; }
dw_offset_t GetTypeOffset() const { return m_type_offset; }
+ uint64_t GetDWOId() const { return m_dwo_id; }
bool IsTypeUnit() const {
return m_unit_type == DW_UT_type || m_unit_type == DW_UT_split_type;
}
@@ -88,6 +89,7 @@ public:
virtual ~DWARFUnit();
bool IsDWOUnit() { return m_is_dwo; }
+ uint64_t GetDWOId();
void ExtractUnitDIEIfNeeded();
void ExtractDIEsIfNeeded();
@@ -105,7 +107,6 @@ public:
};
ScopedExtractDIEs ExtractDIEsScoped();
- DWARFDIE LookupAddress(const dw_addr_t address);
bool Verify(lldb_private::Stream *s) const;
virtual void Dump(lldb_private::Stream *s) const = 0;
/// Get the data that contains the DIE information for this unit.
@@ -167,7 +168,7 @@ public:
void SetBaseAddress(dw_addr_t base_addr);
- DWARFBaseDIE GetUnitDIEOnly() { return DWARFDIE(this, GetUnitDIEPtrOnly()); }
+ DWARFBaseDIE GetUnitDIEOnly() { return {this, GetUnitDIEPtrOnly()}; }
DWARFDIE DIE() { return DWARFDIE(this, DIEPtr()); }
@@ -237,7 +238,9 @@ public:
llvm::Optional<uint64_t> GetRnglistOffset(uint32_t Index) const {
if (!m_rnglist_table)
return llvm::None;
- if (llvm::Optional<uint64_t> off = m_rnglist_table->getOffsetEntry(Index))
+ if (llvm::Optional<uint64_t> off = m_rnglist_table->getOffsetEntry(
+ m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(),
+ Index))
return *off + m_ranges_base;
return llvm::None;
}
@@ -246,7 +249,8 @@ public:
if (!m_loclist_table_header)
return llvm::None;
- llvm::Optional<uint64_t> Offset = m_loclist_table_header->getOffsetEntry(Index);
+ llvm::Optional<uint64_t> Offset = m_loclist_table_header->getOffsetEntry(
+ m_dwarf.GetDWARFContext().getOrLoadLocListsData().GetAsLLVM(), Index);
if (!Offset)
return llvm::None;
return *Offset + m_loclists_base;
@@ -331,6 +335,8 @@ protected:
const DIERef::Section m_section;
bool m_is_dwo;
+ /// Value of DW_AT_GNU_dwo_id (v4) or dwo_id from CU header (v5).
+ uint64_t m_dwo_id;
private:
void ParseProducerInfo();
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
index 7bf4b52bc783..dda599baffeb 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -28,8 +28,7 @@ void ManualDWARFIndex::Index() {
SymbolFileDWARF &main_dwarf = *m_dwarf;
m_dwarf = nullptr;
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%p", static_cast<void *>(&main_dwarf));
+ LLDB_SCOPED_TIMERF("%p", static_cast<void *>(&main_dwarf));
DWARFDebugInfo &main_info = main_dwarf.DebugInfo();
SymbolFileDWARFDwo *dwp_dwarf = main_dwarf.GetDwpSymbolFile().get();
@@ -73,7 +72,7 @@ void ManualDWARFIndex::Index() {
// Share one thread pool across operations to avoid the overhead of
// recreating the threads.
- llvm::ThreadPool pool;
+ llvm::ThreadPool pool(llvm::optimal_concurrency(units_to_index.size()));
// Create a task runner that extracts dies for each DWARF unit in a
// separate thread.
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 0b7e31ae2d1d..3656c7333f27 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -35,6 +35,7 @@
#include "lldb/Interpreter/OptionValueProperties.h"
#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/CompileUnit.h"
@@ -372,24 +373,23 @@ void SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
TypeSet type_set;
CompileUnit *comp_unit = nullptr;
- DWARFUnit *dwarf_cu = nullptr;
if (sc_scope)
comp_unit = sc_scope->CalculateSymbolContextCompileUnit();
- if (comp_unit) {
- dwarf_cu = GetDWARFCompileUnit(comp_unit);
- if (!dwarf_cu)
+ const auto &get = [&](DWARFUnit *unit) {
+ if (!unit)
return;
- GetTypes(dwarf_cu->DIE(), dwarf_cu->GetOffset(),
- dwarf_cu->GetNextUnitOffset(), type_mask, type_set);
+ unit = &unit->GetNonSkeletonUnit();
+ GetTypes(unit->DIE(), unit->GetOffset(), unit->GetNextUnitOffset(),
+ type_mask, type_set);
+ };
+ if (comp_unit) {
+ get(GetDWARFCompileUnit(comp_unit));
} else {
DWARFDebugInfo &info = DebugInfo();
const size_t num_cus = info.GetNumUnits();
- for (size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx) {
- dwarf_cu = info.GetUnitAtIndex(cu_idx);
- if (dwarf_cu)
- GetTypes(dwarf_cu->DIE(), 0, UINT32_MAX, type_mask, type_set);
- }
+ for (size_t cu_idx = 0; cu_idx < num_cus; ++cu_idx)
+ get(info.GetUnitAtIndex(cu_idx));
}
std::set<CompilerType> compiler_type_set;
@@ -624,16 +624,14 @@ DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
DWARFDebugInfo &SymbolFileDWARF::DebugInfo() {
llvm::call_once(m_info_once_flag, [&] {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
+ LLDB_SCOPED_TIMERF("%s this = %p", LLVM_PRETTY_FUNCTION,
static_cast<void *>(this));
m_info = std::make_unique<DWARFDebugInfo>(*this, m_context);
});
return *m_info;
}
-DWARFUnit *
-SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
+DWARFCompileUnit *SymbolFileDWARF::GetDWARFCompileUnit(CompileUnit *comp_unit) {
if (!comp_unit)
return nullptr;
@@ -641,13 +639,14 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
DWARFUnit *dwarf_cu = DebugInfo().GetUnitAtIndex(comp_unit->GetID());
if (dwarf_cu && dwarf_cu->GetUserData() == nullptr)
dwarf_cu->SetUserData(comp_unit);
- return dwarf_cu;
+
+ // It must be DWARFCompileUnit when it created a CompileUnit.
+ return llvm::cast_or_null<DWARFCompileUnit>(dwarf_cu);
}
DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() {
if (!m_ranges) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
+ LLDB_SCOPED_TIMERF("%s this = %p", LLVM_PRETTY_FUNCTION,
static_cast<void *>(this));
if (m_context.getOrLoadRangesData().GetByteSize() > 0)
@@ -829,8 +828,7 @@ XcodeSDK SymbolFileDWARF::ParseXcodeSDK(CompileUnit &comp_unit) {
}
size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "SymbolFileDWARF::ParseFunctions");
+ LLDB_SCOPED_TIMER();
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (!dwarf_cu)
@@ -1267,9 +1265,10 @@ user_id_t SymbolFileDWARF::GetUID(DIERef ref) {
if (GetDebugMapSymfile())
return GetID() | ref.die_offset();
- return user_id_t(GetDwoNum().getValueOr(0x7fffffff)) << 32 |
- ref.die_offset() |
- (lldb::user_id_t(ref.section() == DIERef::Section::DebugTypes) << 63);
+ lldbassert(GetDwoNum().getValueOr(0) <= 0x3fffffff);
+ return user_id_t(GetDwoNum().getValueOr(0)) << 32 | ref.die_offset() |
+ lldb::user_id_t(GetDwoNum().hasValue()) << 62 |
+ lldb::user_id_t(ref.section() == DIERef::Section::DebugTypes) << 63;
}
llvm::Optional<SymbolFileDWARF::DecodedUID>
@@ -1297,9 +1296,10 @@ SymbolFileDWARF::DecodeUID(lldb::user_id_t uid) {
DIERef::Section section =
uid >> 63 ? DIERef::Section::DebugTypes : DIERef::Section::DebugInfo;
- llvm::Optional<uint32_t> dwo_num = uid >> 32 & 0x7fffffff;
- if (*dwo_num == 0x7fffffff)
- dwo_num = llvm::None;
+ llvm::Optional<uint32_t> dwo_num;
+ bool dwo_valid = uid >> 62 & 1;
+ if (dwo_valid)
+ dwo_num = uid >> 32 & 0x3fffffff;
return DecodedUID{*this, {dwo_num, section, die_offset}};
}
@@ -1599,8 +1599,7 @@ static uint64_t GetDWOId(DWARFCompileUnit &dwarf_cu,
llvm::Optional<uint64_t> SymbolFileDWARF::GetDWOId() {
if (GetNumCompileUnits() == 1) {
if (auto comp_unit = GetCompileUnitAtIndex(0))
- if (DWARFCompileUnit *cu = llvm::dyn_cast_or_null<DWARFCompileUnit>(
- GetDWARFCompileUnit(comp_unit.get())))
+ if (DWARFCompileUnit *cu = GetDWARFCompileUnit(comp_unit.get()))
if (DWARFDebugInfoEntry *cu_die = cu->DIE().GetDIE())
if (uint64_t dwo_id = ::GetDWOId(*cu, *cu_die))
return dwo_id;
@@ -1791,7 +1790,7 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
lldb::addr_t byte_size = 1;
if (var_sp->GetType())
byte_size =
- var_sp->GetType()->GetByteSize().getValueOr(0);
+ var_sp->GetType()->GetByteSize(nullptr).getValueOr(0);
m_global_aranges_up->Append(GlobalVariableMap::Entry(
file_addr, byte_size, var_sp.get()));
}
@@ -1811,7 +1810,8 @@ void SymbolFileDWARF::ResolveFunctionAndBlock(lldb::addr_t file_vm_addr,
bool lookup_block,
SymbolContext &sc) {
assert(sc.comp_unit);
- DWARFUnit &cu = GetDWARFCompileUnit(sc.comp_unit)->GetNonSkeletonUnit();
+ DWARFCompileUnit &cu =
+ GetDWARFCompileUnit(sc.comp_unit)->GetNonSkeletonUnit();
DWARFDIE function_die = cu.LookupAddress(file_vm_addr);
DWARFDIE block_die;
if (function_die) {
@@ -1837,9 +1837,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
SymbolContextItem resolve_scope,
SymbolContext &sc) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat,
- "SymbolFileDWARF::"
+ LLDB_SCOPED_TIMERF("SymbolFileDWARF::"
"ResolveSymbolContext (so_addr = { "
"section = %p, offset = 0x%" PRIx64
" }, resolve_scope = 0x%8.8x)",
@@ -2275,8 +2273,7 @@ void SymbolFileDWARF::FindFunctions(ConstString name,
bool include_inlines,
SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "SymbolFileDWARF::FindFunctions (name = '%s')",
+ LLDB_SCOPED_TIMERF("SymbolFileDWARF::FindFunctions (name = '%s')",
name.AsCString());
// eFunctionNameTypeAuto should be pre-resolved by a call to
@@ -2330,8 +2327,7 @@ void SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
bool include_inlines,
SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "SymbolFileDWARF::FindFunctions (regex = '%s')",
+ LLDB_SCOPED_TIMERF("SymbolFileDWARF::FindFunctions (regex = '%s')",
regex.GetText().str().c_str());
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
@@ -3045,8 +3041,12 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
if (sc.function) {
DWARFDIE function_die = GetDIE(sc.function->GetID());
- const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress(
- DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+ dw_addr_t func_lo_pc = LLDB_INVALID_ADDRESS;
+ DWARFRangeList ranges;
+ if (function_die.GetDIE()->GetAttributeAddressRanges(
+ function_die.GetCU(), ranges,
+ /*check_hi_lo_pc=*/true))
+ func_lo_pc = ranges.GetMinRangeBase(0);
if (func_lo_pc != LLDB_INVALID_ADDRESS) {
const size_t num_variables = ParseVariables(
sc, function_die.GetFirstChild(), func_lo_pc, true, true);
@@ -3091,385 +3091,348 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
if (die.GetDWARF() != this)
return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc);
- VariableSP var_sp;
if (!die)
- return var_sp;
+ return nullptr;
- var_sp = GetDIEToVariable()[die.GetDIE()];
- if (var_sp)
+ if (VariableSP var_sp = GetDIEToVariable()[die.GetDIE()])
return var_sp; // Already been parsed!
const dw_tag_t tag = die.Tag();
ModuleSP module = GetObjectFile()->GetModule();
- if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) ||
- (tag == DW_TAG_formal_parameter && sc.function)) {
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes(attributes);
- DWARFDIE spec_die;
- if (num_attributes > 0) {
- const char *name = nullptr;
- const char *mangled = nullptr;
- Declaration decl;
- uint32_t i;
- DWARFFormValue type_die_form;
- DWARFExpression location;
- bool is_external = false;
- bool is_artificial = false;
- 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) {
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
-
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_decl_file:
- decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
- form_value.Unsigned()));
- break;
- case DW_AT_decl_line:
- decl.SetLine(form_value.Unsigned());
- break;
- case DW_AT_decl_column:
- decl.SetColumn(form_value.Unsigned());
- break;
- case DW_AT_name:
- name = form_value.AsCString();
- break;
- case DW_AT_linkage_name:
- case DW_AT_MIPS_linkage_name:
- mangled = form_value.AsCString();
- break;
- case DW_AT_type:
- type_die_form = form_value;
- break;
- case DW_AT_external:
- is_external = form_value.Boolean();
- break;
- case DW_AT_const_value:
- // If we have already found a DW_AT_location attribute, ignore this
- // attribute.
- if (!has_explicit_location) {
- location_is_const_value_data = true;
- // The constant value will be either a block, a data value or a
- // string.
- auto debug_info_data = die.GetData();
- if (DWARFFormValue::IsBlockForm(form_value.Form())) {
- // Retrieve the value as a block expression.
- uint32_t block_offset =
- form_value.BlockData() - debug_info_data.GetDataStart();
- uint32_t block_length = form_value.Unsigned();
- location = DWARFExpression(
- module,
- DataExtractor(debug_info_data, block_offset, block_length),
- die.GetCU());
- } else if (DWARFFormValue::IsDataForm(form_value.Form())) {
- // Retrieve the value as a data expression.
- uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
- if (auto data_length = form_value.GetFixedSize())
- location = DWARFExpression(
- module,
- DataExtractor(debug_info_data, data_offset, *data_length),
- die.GetCU());
- else {
- const uint8_t *data_pointer = form_value.BlockData();
- if (data_pointer) {
- form_value.Unsigned();
- } else if (DWARFFormValue::IsDataForm(form_value.Form())) {
- // we need to get the byte size of the type later after we
- // create the variable
- const_value = form_value;
- }
- }
- } else {
- // Retrieve the value as a string expression.
- if (form_value.Form() == DW_FORM_strp) {
- uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
- if (auto data_length = form_value.GetFixedSize())
- location = DWARFExpression(module,
- DataExtractor(debug_info_data,
- data_offset,
- *data_length),
- die.GetCU());
- } else {
- const char *str = form_value.AsCString();
- uint32_t string_offset =
- str - (const char *)debug_info_data.GetDataStart();
- uint32_t string_length = strlen(str) + 1;
- location = DWARFExpression(module,
- DataExtractor(debug_info_data,
- string_offset,
- string_length),
- die.GetCU());
- }
- }
- }
- break;
- case DW_AT_location: {
- location_is_const_value_data = false;
- has_explicit_location = true;
- if (DWARFFormValue::IsBlockForm(form_value.Form())) {
- auto data = die.GetData();
-
- uint32_t block_offset =
- form_value.BlockData() - data.GetDataStart();
- uint32_t block_length = form_value.Unsigned();
- location = DWARFExpression(
- module, DataExtractor(data, block_offset, block_length),
- die.GetCU());
- } else {
- DataExtractor data = die.GetCU()->GetLocationData();
- dw_offset_t offset = form_value.Unsigned();
- if (form_value.Form() == DW_FORM_loclistx)
- offset = die.GetCU()->GetLoclistOffset(offset).getValueOr(-1);
- if (data.ValidOffset(offset)) {
- data = DataExtractor(data, offset, data.GetByteSize() - offset);
- location = DWARFExpression(module, data, die.GetCU());
- assert(func_low_pc != LLDB_INVALID_ADDRESS);
- location.SetLocationListAddresses(
- attributes.CompileUnitAtIndex(i)->GetBaseAddress(),
- func_low_pc);
- }
- }
- } break;
- case DW_AT_specification:
- spec_die = form_value.Reference();
- break;
- case DW_AT_start_scope:
- // TODO: Implement this.
- 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_visibility:
- default:
- case DW_AT_abstract_origin:
- case DW_AT_sibling:
- break;
- }
- }
- }
+ if (tag != DW_TAG_variable && tag != DW_TAG_constant &&
+ (tag != DW_TAG_formal_parameter || !sc.function))
+ return nullptr;
+
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ DWARFDIE spec_die;
+ VariableSP var_sp;
+ const char *name = nullptr;
+ const char *mangled = nullptr;
+ Declaration decl;
+ DWARFFormValue type_die_form;
+ DWARFExpression location;
+ bool is_external = false;
+ bool is_artificial = false;
+ DWARFFormValue const_value_form, location_form;
+ Variable::RangeList scope_ranges;
+
+ for (size_t i = 0; i < num_attributes; ++i) {
+ dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+
+ if (!attributes.ExtractFormValueAtIndex(i, form_value))
+ continue;
+ switch (attr) {
+ case DW_AT_decl_file:
+ decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
+ form_value.Unsigned()));
+ break;
+ case DW_AT_decl_line:
+ decl.SetLine(form_value.Unsigned());
+ break;
+ case DW_AT_decl_column:
+ decl.SetColumn(form_value.Unsigned());
+ break;
+ case DW_AT_name:
+ name = form_value.AsCString();
+ break;
+ case DW_AT_linkage_name:
+ case DW_AT_MIPS_linkage_name:
+ mangled = form_value.AsCString();
+ break;
+ case DW_AT_type:
+ type_die_form = form_value;
+ break;
+ case DW_AT_external:
+ is_external = form_value.Boolean();
+ break;
+ case DW_AT_const_value:
+ const_value_form = form_value;
+ break;
+ case DW_AT_location:
+ location_form = form_value;
+ break;
+ case DW_AT_specification:
+ spec_die = form_value.Reference();
+ break;
+ case DW_AT_start_scope:
+ // TODO: Implement this.
+ break;
+ case DW_AT_artificial:
+ is_artificial = form_value.Boolean();
+ break;
+ case DW_AT_declaration:
+ case DW_AT_description:
+ case DW_AT_endianity:
+ case DW_AT_segment:
+ case DW_AT_visibility:
+ default:
+ case DW_AT_abstract_origin:
+ case DW_AT_sibling:
+ break;
+ }
+ }
- const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
- const dw_tag_t parent_tag = die.GetParent().Tag();
- bool is_static_member =
- (parent_tag == DW_TAG_compile_unit ||
- parent_tag == DW_TAG_partial_unit) &&
- (parent_context_die.Tag() == DW_TAG_class_type ||
- parent_context_die.Tag() == DW_TAG_structure_type);
-
- ValueType scope = eValueTypeInvalid;
-
- const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
- SymbolContextScope *symbol_context_scope = nullptr;
-
- bool has_explicit_mangled = mangled != nullptr;
- if (!mangled) {
- // LLDB relies on the mangled name (DW_TAG_linkage_name or
- // DW_AT_MIPS_linkage_name) to generate fully qualified names
- // of global variables with commands like "frame var j". For
- // example, if j were an int variable holding a value 4 and
- // declared in a namespace B which in turn is contained in a
- // namespace A, the command "frame var j" returns
- // "(int) A::B::j = 4".
- // If the compiler does not emit a linkage name, we should be
- // able to generate a fully qualified name from the
- // declaration context.
- if ((parent_tag == DW_TAG_compile_unit ||
- parent_tag == DW_TAG_partial_unit) &&
- Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU())))
- mangled = GetDWARFDeclContext(die)
- .GetQualifiedNameAsConstString()
- .GetCString();
+ // Prefer DW_AT_location over DW_AT_const_value. Both can be emitted e.g.
+ // for static constexpr member variables -- DW_AT_const_value will be
+ // present in the class declaration and DW_AT_location in the DIE defining
+ // the member.
+ bool location_is_const_value_data = false;
+ bool has_explicit_location = false;
+ bool use_type_size_for_value = false;
+ if (location_form.IsValid()) {
+ has_explicit_location = true;
+ if (DWARFFormValue::IsBlockForm(location_form.Form())) {
+ const DWARFDataExtractor &data = die.GetData();
+
+ uint32_t block_offset = location_form.BlockData() - data.GetDataStart();
+ uint32_t block_length = location_form.Unsigned();
+ location = DWARFExpression(
+ module, DataExtractor(data, block_offset, block_length), die.GetCU());
+ } else {
+ DataExtractor data = die.GetCU()->GetLocationData();
+ dw_offset_t offset = location_form.Unsigned();
+ if (location_form.Form() == DW_FORM_loclistx)
+ offset = die.GetCU()->GetLoclistOffset(offset).getValueOr(-1);
+ if (data.ValidOffset(offset)) {
+ data = DataExtractor(data, offset, data.GetByteSize() - offset);
+ location = DWARFExpression(module, data, die.GetCU());
+ assert(func_low_pc != LLDB_INVALID_ADDRESS);
+ location.SetLocationListAddresses(
+ location_form.GetUnit()->GetBaseAddress(), func_low_pc);
}
+ }
+ } else if (const_value_form.IsValid()) {
+ location_is_const_value_data = true;
+ // The constant value will be either a block, a data value or a
+ // string.
+ const DWARFDataExtractor &debug_info_data = die.GetData();
+ if (DWARFFormValue::IsBlockForm(const_value_form.Form())) {
+ // Retrieve the value as a block expression.
+ uint32_t block_offset =
+ const_value_form.BlockData() - debug_info_data.GetDataStart();
+ uint32_t block_length = const_value_form.Unsigned();
+ location = DWARFExpression(
+ module, DataExtractor(debug_info_data, block_offset, block_length),
+ die.GetCU());
+ } else if (DWARFFormValue::IsDataForm(const_value_form.Form())) {
+ // Constant value size does not have to match the size of the
+ // variable. We will fetch the size of the type after we create
+ // it.
+ use_type_size_for_value = true;
+ } else if (const char *str = const_value_form.AsCString()) {
+ uint32_t string_length = strlen(str) + 1;
+ location = DWARFExpression(
+ module,
+ DataExtractor(str, string_length, die.GetCU()->GetByteOrder(),
+ die.GetCU()->GetAddressByteSize()),
+ die.GetCU());
+ }
+ }
- if (tag == DW_TAG_formal_parameter)
- scope = eValueTypeVariableArgument;
- else {
- // DWARF doesn't specify if a DW_TAG_variable is a local, global
- // or static variable, so we have to do a little digging:
- // 1) DW_AT_linkage_name implies static lifetime (but may be missing)
- // 2) An empty DW_AT_location is an (optimized-out) static lifetime var.
- // 3) DW_AT_location containing a DW_OP_addr implies static lifetime.
- // Clang likes to combine small global variables into the same symbol
- // with locations like: DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
- // so we need to look through the whole expression.
- bool is_static_lifetime =
- has_explicit_mangled ||
- (has_explicit_location && !location.IsValid());
- // Check if the location has a DW_OP_addr with any address value...
- lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
- if (!location_is_const_value_data) {
- bool op_error = false;
- location_DW_OP_addr = location.GetLocation_DW_OP_addr(0, op_error);
- if (op_error) {
- StreamString strm;
- location.DumpLocationForAddress(&strm, eDescriptionLevelFull, 0, 0,
- nullptr);
- GetObjectFile()->GetModule()->ReportError(
- "0x%8.8x: %s has an invalid location: %s", die.GetOffset(),
- die.GetTagAsCString(), strm.GetData());
- }
- if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
- is_static_lifetime = true;
- }
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile)
- // Set the module of the expression to the linked module
- // instead of the oject file so the relocated address can be
- // found there.
- location.SetModule(debug_map_symfile->GetObjectFile()->GetModule());
-
- if (is_static_lifetime) {
- if (is_external)
- scope = eValueTypeVariableGlobal;
- else
- scope = eValueTypeVariableStatic;
-
- if (debug_map_symfile) {
- // When leaving the DWARF in the .o files on darwin, when we have a
- // global variable that wasn't initialized, the .o file might not
- // have allocated a virtual address for the global variable. In
- // this case it will have created a symbol for the global variable
- // that is undefined/data and external and the value will be the
- // byte size of the variable. When we do the address map in
- // SymbolFileDWARFDebugMap we rely on having an address, we need to
- // do some magic here so we can get the correct address for our
- // global variable. The address for all of these entries will be
- // zero, and there will be an undefined symbol in this object file,
- // and the executable will have a matching symbol with a good
- // address. So here we dig up the correct address and replace it in
- // the location for the variable, and set the variable's symbol
- // context scope to be that of the main executable so the file
- // address will resolve correctly.
- bool linked_oso_file_addr = false;
- if (is_external && location_DW_OP_addr == 0) {
- // we have a possible uninitialized extern global
- ConstString const_name(mangled ? mangled : name);
- ObjectFile *debug_map_objfile =
- debug_map_symfile->GetObjectFile();
- if (debug_map_objfile) {
- Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
- if (debug_map_symtab) {
- Symbol *exe_symbol =
- debug_map_symtab->FindFirstSymbolWithNameAndType(
- const_name, eSymbolTypeData, Symtab::eDebugYes,
- Symtab::eVisibilityExtern);
- if (exe_symbol) {
- if (exe_symbol->ValueIsAddress()) {
- const addr_t exe_file_addr =
- exe_symbol->GetAddressRef().GetFileAddress();
- if (exe_file_addr != LLDB_INVALID_ADDRESS) {
- if (location.Update_DW_OP_addr(exe_file_addr)) {
- linked_oso_file_addr = true;
- symbol_context_scope = exe_symbol;
- }
- }
+ const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
+ const dw_tag_t parent_tag = die.GetParent().Tag();
+ bool is_static_member = (parent_tag == DW_TAG_compile_unit ||
+ parent_tag == DW_TAG_partial_unit) &&
+ (parent_context_die.Tag() == DW_TAG_class_type ||
+ parent_context_die.Tag() == DW_TAG_structure_type);
+
+ ValueType scope = eValueTypeInvalid;
+
+ const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
+ SymbolContextScope *symbol_context_scope = nullptr;
+
+ bool has_explicit_mangled = mangled != nullptr;
+ if (!mangled) {
+ // LLDB relies on the mangled name (DW_TAG_linkage_name or
+ // DW_AT_MIPS_linkage_name) to generate fully qualified names
+ // of global variables with commands like "frame var j". For
+ // example, if j were an int variable holding a value 4 and
+ // declared in a namespace B which in turn is contained in a
+ // namespace A, the command "frame var j" returns
+ // "(int) A::B::j = 4".
+ // If the compiler does not emit a linkage name, we should be
+ // able to generate a fully qualified name from the
+ // declaration context.
+ if ((parent_tag == DW_TAG_compile_unit ||
+ parent_tag == DW_TAG_partial_unit) &&
+ Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU())))
+ mangled =
+ GetDWARFDeclContext(die).GetQualifiedNameAsConstString().GetCString();
+ }
+
+ if (tag == DW_TAG_formal_parameter)
+ scope = eValueTypeVariableArgument;
+ else {
+ // DWARF doesn't specify if a DW_TAG_variable is a local, global
+ // or static variable, so we have to do a little digging:
+ // 1) DW_AT_linkage_name implies static lifetime (but may be missing)
+ // 2) An empty DW_AT_location is an (optimized-out) static lifetime var.
+ // 3) DW_AT_location containing a DW_OP_addr implies static lifetime.
+ // Clang likes to combine small global variables into the same symbol
+ // with locations like: DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
+ // so we need to look through the whole expression.
+ bool is_static_lifetime =
+ has_explicit_mangled || (has_explicit_location && !location.IsValid());
+ // Check if the location has a DW_OP_addr with any address value...
+ lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
+ if (!location_is_const_value_data) {
+ bool op_error = false;
+ location_DW_OP_addr = location.GetLocation_DW_OP_addr(0, op_error);
+ if (op_error) {
+ StreamString strm;
+ location.DumpLocationForAddress(&strm, eDescriptionLevelFull, 0, 0,
+ nullptr);
+ GetObjectFile()->GetModule()->ReportError(
+ "0x%8.8x: %s has an invalid location: %s", die.GetOffset(),
+ die.GetTagAsCString(), strm.GetData());
+ }
+ if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
+ is_static_lifetime = true;
+ }
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile)
+ // Set the module of the expression to the linked module
+ // instead of the oject file so the relocated address can be
+ // found there.
+ location.SetModule(debug_map_symfile->GetObjectFile()->GetModule());
+
+ if (is_static_lifetime) {
+ if (is_external)
+ scope = eValueTypeVariableGlobal;
+ else
+ scope = eValueTypeVariableStatic;
+
+ if (debug_map_symfile) {
+ // When leaving the DWARF in the .o files on darwin, when we have a
+ // global variable that wasn't initialized, the .o file might not
+ // have allocated a virtual address for the global variable. In
+ // this case it will have created a symbol for the global variable
+ // that is undefined/data and external and the value will be the
+ // byte size of the variable. When we do the address map in
+ // SymbolFileDWARFDebugMap we rely on having an address, we need to
+ // do some magic here so we can get the correct address for our
+ // global variable. The address for all of these entries will be
+ // zero, and there will be an undefined symbol in this object file,
+ // and the executable will have a matching symbol with a good
+ // address. So here we dig up the correct address and replace it in
+ // the location for the variable, and set the variable's symbol
+ // context scope to be that of the main executable so the file
+ // address will resolve correctly.
+ bool linked_oso_file_addr = false;
+ if (is_external && location_DW_OP_addr == 0) {
+ // we have a possible uninitialized extern global
+ ConstString const_name(mangled ? mangled : name);
+ ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
+ if (debug_map_objfile) {
+ Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
+ if (debug_map_symtab) {
+ Symbol *exe_symbol =
+ debug_map_symtab->FindFirstSymbolWithNameAndType(
+ const_name, eSymbolTypeData, Symtab::eDebugYes,
+ Symtab::eVisibilityExtern);
+ if (exe_symbol) {
+ if (exe_symbol->ValueIsAddress()) {
+ const addr_t exe_file_addr =
+ exe_symbol->GetAddressRef().GetFileAddress();
+ if (exe_file_addr != LLDB_INVALID_ADDRESS) {
+ if (location.Update_DW_OP_addr(exe_file_addr)) {
+ linked_oso_file_addr = true;
+ symbol_context_scope = exe_symbol;
}
}
}
}
}
-
- if (!linked_oso_file_addr) {
- // The DW_OP_addr is not zero, but it contains a .o file address
- // which needs to be linked up correctly.
- const lldb::addr_t exe_file_addr =
- debug_map_symfile->LinkOSOFileAddress(this,
- location_DW_OP_addr);
- if (exe_file_addr != LLDB_INVALID_ADDRESS) {
- // Update the file address for this variable
- location.Update_DW_OP_addr(exe_file_addr);
- } else {
- // Variable didn't make it into the final executable
- return var_sp;
- }
- }
}
- } else {
- if (location_is_const_value_data &&
- die.GetDIE()->IsGlobalOrStaticScopeVariable())
- 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;
- }
- }
+ }
+
+ if (!linked_oso_file_addr) {
+ // The DW_OP_addr is not zero, but it contains a .o file address
+ // which needs to be linked up correctly.
+ const lldb::addr_t exe_file_addr =
+ debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
+ if (exe_file_addr != LLDB_INVALID_ADDRESS) {
+ // Update the file address for this variable
+ location.Update_DW_OP_addr(exe_file_addr);
+ } else {
+ // Variable didn't make it into the final executable
+ return var_sp;
}
}
}
-
- if (symbol_context_scope == nullptr) {
- switch (parent_tag) {
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_lexical_block:
- if (sc.function) {
- symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(
- sc_parent_die.GetID());
- if (symbol_context_scope == nullptr)
- symbol_context_scope = sc.function;
+ } else {
+ if (location_is_const_value_data &&
+ die.GetDIE()->IsGlobalOrStaticScopeVariable())
+ 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;
}
- break;
-
- default:
- symbol_context_scope = sc.comp_unit;
- break;
}
}
+ }
+ }
- if (symbol_context_scope) {
- SymbolFileTypeSP type_sp(
- new SymbolFileType(*this, GetUID(type_die_form.Reference())));
+ if (symbol_context_scope == nullptr) {
+ switch (parent_tag) {
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_lexical_block:
+ if (sc.function) {
+ symbol_context_scope =
+ sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
+ if (symbol_context_scope == nullptr)
+ symbol_context_scope = sc.function;
+ }
+ break;
- if (const_value.Form() && type_sp && type_sp->GetType())
- location.UpdateValue(const_value.Unsigned(),
- type_sp->GetType()->GetByteSize().getValueOr(0),
- die.GetCU()->GetAddressByteSize());
+ default:
+ symbol_context_scope = sc.comp_unit;
+ break;
+ }
+ }
- var_sp = std::make_shared<Variable>(
- die.GetID(), name, mangled, type_sp, scope, symbol_context_scope,
- scope_ranges, &decl, location, is_external, is_artificial,
- is_static_member);
+ if (symbol_context_scope) {
+ auto type_sp = std::make_shared<SymbolFileType>(
+ *this, GetUID(type_die_form.Reference()));
- var_sp->SetLocationIsConstantValueData(location_is_const_value_data);
- } else {
- // Not ready to parse this variable yet. It might be a global or static
- // variable that is in a function scope and the function in the symbol
- // context wasn't filled in yet
- return var_sp;
- }
- }
- // Cache var_sp even if NULL (the variable was just a specification or was
- // missing vital information to be able to be displayed in the debugger
- // (missing location due to optimization, etc)) so we don't re-parse this
- // DIE over and over later...
- GetDIEToVariable()[die.GetDIE()] = var_sp;
- if (spec_die)
- GetDIEToVariable()[spec_die.GetDIE()] = var_sp;
+ if (use_type_size_for_value && type_sp->GetType())
+ location.UpdateValue(
+ const_value_form.Unsigned(),
+ type_sp->GetType()->GetByteSize(nullptr).getValueOr(0),
+ die.GetCU()->GetAddressByteSize());
+
+ var_sp = std::make_shared<Variable>(
+ die.GetID(), name, mangled, type_sp, scope, symbol_context_scope,
+ scope_ranges, &decl, location, is_external, is_artificial,
+ location_is_const_value_data, is_static_member);
+ } else {
+ // Not ready to parse this variable yet. It might be a global or static
+ // variable that is in a function scope and the function in the symbol
+ // context wasn't filled in yet
+ return var_sp;
}
+ // Cache var_sp even if NULL (the variable was just a specification or was
+ // missing vital information to be able to be displayed in the debugger
+ // (missing location due to optimization, etc)) so we don't re-parse this
+ // DIE over and over later...
+ GetDIEToVariable()[die.GetDIE()] = var_sp;
+ if (spec_die)
+ GetDIEToVariable()[spec_die.GetDIE()] = var_sp;
+
return var_sp;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 76ceb279c718..019f76c67c63 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -346,7 +346,7 @@ protected:
lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu);
- virtual DWARFUnit *
+ virtual DWARFCompileUnit *
GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit);
DWARFUnit *GetNextUnparsedDWARFCompileUnit(DWARFUnit *prev_cu);
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index 6515d78b8f23..fa24f975b073 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -1013,9 +1013,7 @@ void SymbolFileDWARFDebugMap::FindFunctions(
FunctionNameType name_type_mask, bool include_inlines,
SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat,
- "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
+ LLDB_SCOPED_TIMERF("SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
name.GetCString());
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
@@ -1034,9 +1032,7 @@ void SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression &regex,
bool include_inlines,
SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat,
- "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
+ LLDB_SCOPED_TIMERF("SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
regex.GetText().str().c_str());
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
@@ -1055,9 +1051,7 @@ void SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
lldb::TypeClass type_mask,
TypeList &type_list) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat,
- "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
+ LLDB_SCOPED_TIMERF("SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
type_mask);
SymbolFileDWARF *oso_dwarf = nullptr;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index 3aaa7d330b84..fcb51dfa0e7a 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -49,8 +49,7 @@ DWARFCompileUnit *SymbolFileDWARFDwo::GetDWOCompileUnitForHash(uint64_t hash) {
DWARFCompileUnit *cu = FindSingleCompileUnit();
if (!cu)
return nullptr;
- if (hash !=
- cu->GetUnitDIEOnly().GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0))
+ if (hash != cu->GetDWOId())
return nullptr;
return cu;
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 0acc77d7c67f..5b4ab78ac219 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -881,8 +881,8 @@ PdbAstBuilder::GetOrCreateTypedefDecl(PdbGlobalSymId id) {
std::string uname = std::string(DropNameScope(udt.Name));
- CompilerType ct = m_clang.CreateTypedefType(ToCompilerType(qt), uname.c_str(),
- ToCompilerDeclContext(*scope), 0);
+ CompilerType ct = ToCompilerType(qt).CreateTypedef(
+ uname.c_str(), ToCompilerDeclContext(*scope), 0);
clang::TypedefNameDecl *tnd = m_clang.GetAsTypedefDecl(ct);
DeclStatus status;
status.resolved = true;
@@ -1015,8 +1015,7 @@ PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) {
proc_name.consume_front("::");
clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration(
- parent, OptionalClangModuleID(), proc_name.str().c_str(), func_ct,
- storage, false);
+ parent, OptionalClangModuleID(), proc_name, func_ct, storage, false);
lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0);
m_uid_to_decl[toOpaqueUid(func_id)] = function_decl;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp
index 6ac6cc2da29b..dc964f64a915 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp
@@ -39,7 +39,7 @@ PdbIndex::PdbIndex() : m_cus(*this), m_va_to_modi(m_allocator) {}
}
llvm::Expected<std::unique_ptr<PdbIndex>>
-PdbIndex::create(std::unique_ptr<llvm::pdb::PDBFile> file) {
+PdbIndex::create(llvm::pdb::PDBFile *file) {
lldbassert(file);
std::unique_ptr<PdbIndex> result(new PdbIndex());
@@ -53,7 +53,7 @@ PdbIndex::create(std::unique_ptr<llvm::pdb::PDBFile> file) {
result->m_tpi->buildHashMap();
- result->m_file = std::move(file);
+ result->m_file = file;
return std::move(result);
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h
index ccc3cc2f4538..1b382e5263c1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h
@@ -48,7 +48,7 @@ struct SegmentOffset;
class PdbIndex {
/// The underlying PDB file.
- std::unique_ptr<llvm::pdb::PDBFile> m_file;
+ llvm::pdb::PDBFile *m_file = nullptr;
/// The DBI stream. This contains general high level information about the
/// features present in the PDB file, compile units (such as the information
@@ -110,8 +110,7 @@ class PdbIndex {
void BuildAddrToSymbolMap(CompilandIndexItem &cci);
public:
- static llvm::Expected<std::unique_ptr<PdbIndex>>
- create(std::unique_ptr<llvm::pdb::PDBFile>);
+ static llvm::Expected<std::unique_ptr<PdbIndex>> create(llvm::pdb::PDBFile *);
void SetLoadAddress(lldb::addr_t addr) { m_load_address = addr; }
lldb::addr_t GetLoadAddress() const { return m_load_address; }
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index cce06473d92f..24b4c64a91bc 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -16,6 +16,7 @@
#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
+#include "Plugins/ObjectFile/PDB/ObjectFilePDB.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
@@ -42,9 +43,11 @@
#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/DebugInfo/PDB/PDB.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
#include "llvm/Demangle/MicrosoftDemangle.h"
#include "llvm/Object/COFF.h"
@@ -81,32 +84,6 @@ static lldb::LanguageType TranslateLanguage(PDB_Lang lang) {
}
}
-static std::unique_ptr<PDBFile> loadPDBFile(std::string PdbPath,
- llvm::BumpPtrAllocator &Allocator) {
- llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ErrorOrBuffer =
- llvm::MemoryBuffer::getFile(PdbPath, /*FileSize=*/-1,
- /*RequiresNullTerminator=*/false);
- if (!ErrorOrBuffer)
- return nullptr;
- std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
-
- llvm::StringRef Path = Buffer->getBufferIdentifier();
- auto Stream = std::make_unique<llvm::MemoryBufferByteStream>(
- std::move(Buffer), llvm::support::little);
-
- auto File = std::make_unique<PDBFile>(Path, std::move(Stream), Allocator);
- if (auto EC = File->parseFileHeaders()) {
- llvm::consumeError(std::move(EC));
- return nullptr;
- }
- if (auto EC = File->parseStreamData()) {
- llvm::consumeError(std::move(EC));
- return nullptr;
- }
-
- return File;
-}
-
static std::unique_ptr<PDBFile>
loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) {
// Try to find a matching PDB for an EXE.
@@ -134,13 +111,17 @@ loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) {
return nullptr;
}
- // if the file doesn't exist, is not a pdb, or doesn't have a matching guid,
- // fail.
- llvm::file_magic magic;
- auto ec = llvm::identify_magic(pdb_file, magic);
- if (ec || magic != llvm::file_magic::pdb)
- return nullptr;
- std::unique_ptr<PDBFile> pdb = loadPDBFile(std::string(pdb_file), allocator);
+ // If the file doesn't exist, perhaps the path specified at build time
+ // doesn't match the PDB's current location, so check the location of the
+ // executable.
+ if (!FileSystem::Instance().Exists(pdb_file)) {
+ const auto exe_dir = FileSpec(exe_path).CopyByRemovingLastPathComponent();
+ const auto pdb_name = FileSpec(pdb_file).GetFilename().GetCString();
+ pdb_file = exe_dir.CopyByAppendingPathComponent(pdb_name).GetCString();
+ }
+
+ // If the file is not a PDB or if it doesn't have a matching GUID, fail.
+ auto pdb = ObjectFilePDB::loadPDBFile(std::string(pdb_file), allocator);
if (!pdb)
return nullptr;
@@ -284,24 +265,19 @@ uint32_t SymbolFileNativePDB::CalculateAbilities() {
if (!m_index) {
// Lazily load and match the PDB file, but only do this once.
- std::unique_ptr<PDBFile> file_up =
- loadMatchingPDBFile(m_objfile_sp->GetFileSpec().GetPath(), m_allocator);
-
- if (!file_up) {
- auto module_sp = m_objfile_sp->GetModule();
- if (!module_sp)
- return 0;
- // See if any symbol file is specified through `--symfile` option.
- FileSpec symfile = module_sp->GetSymbolFileFileSpec();
- if (!symfile)
- return 0;
- file_up = loadPDBFile(symfile.GetPath(), m_allocator);
+ PDBFile *pdb_file;
+ if (auto *pdb = llvm::dyn_cast<ObjectFilePDB>(m_objfile_sp.get())) {
+ pdb_file = &pdb->GetPDBFile();
+ } else {
+ m_file_up = loadMatchingPDBFile(m_objfile_sp->GetFileSpec().GetPath(),
+ m_allocator);
+ pdb_file = m_file_up.get();
}
- if (!file_up)
+ if (!pdb_file)
return 0;
- auto expected_index = PdbIndex::create(std::move(file_up));
+ auto expected_index = PdbIndex::create(pdb_file);
if (!expected_index) {
llvm::consumeError(expected_index.takeError());
return 0;
@@ -321,7 +297,10 @@ uint32_t SymbolFileNativePDB::CalculateAbilities() {
}
void SymbolFileNativePDB::InitializeObject() {
- m_obj_load_address = m_objfile_sp->GetBaseAddress().GetFileAddress();
+ m_obj_load_address = m_objfile_sp->GetModule()
+ ->GetObjectFile()
+ ->GetBaseAddress()
+ .GetFileAddress();
m_index->SetLoadAddress(m_obj_load_address);
m_index->ParseSectionContribs();
@@ -460,7 +439,7 @@ lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbTypeSymId type_id,
lldb::TypeSP modified_type = GetOrCreateType(mr.ModifiedType);
return std::make_shared<Type>(toOpaqueUid(type_id), this, ConstString(name),
- modified_type->GetByteSize(), nullptr,
+ modified_type->GetByteSize(nullptr), nullptr,
LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
ct, Type::ResolveState::Full);
}
@@ -584,7 +563,7 @@ lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,
return std::make_shared<lldb_private::Type>(
toOpaqueUid(type_id), this, ConstString(uname),
- underlying_type->GetByteSize(), nullptr, LLDB_INVALID_UID,
+ underlying_type->GetByteSize(nullptr), nullptr, LLDB_INVALID_UID,
lldb_private::Type::eEncodingIsUID, decl, ct,
lldb_private::Type::ResolveState::Forward);
}
@@ -809,11 +788,13 @@ VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) {
std::string global_name("::");
global_name += name;
+ bool artificial = false;
+ bool location_is_constant_data = false;
+ bool static_member = false;
VariableSP var_sp = std::make_shared<Variable>(
toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp,
- scope, comp_unit.get(), ranges, &decl, location, is_external, false,
- false);
- var_sp->SetLocationIsConstantValueData(false);
+ scope, comp_unit.get(), ranges, &decl, location, is_external, artificial,
+ location_is_constant_data, static_member);
return var_sp;
}
@@ -837,11 +818,14 @@ SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id,
DWARFExpression location = MakeConstantLocationExpression(
constant.Type, tpi, constant.Value, module);
+ bool external = false;
+ bool artificial = false;
+ bool location_is_constant_data = true;
+ bool static_member = false;
VariableSP var_sp = std::make_shared<Variable>(
toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(),
type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location,
- false, false, false);
- var_sp->SetLocationIsConstantValueData(true);
+ external, artificial, location_is_constant_data, static_member);
return var_sp;
}
@@ -1343,10 +1327,14 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
ValueType var_scope =
is_param ? eValueTypeVariableArgument : eValueTypeVariableLocal;
+ bool external = false;
+ bool artificial = false;
+ bool location_is_constant_data = false;
+ bool static_member = false;
VariableSP var_sp = std::make_shared<Variable>(
toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope,
- comp_unit_sp.get(), *var_info.ranges, &decl, *var_info.location, false,
- false, false);
+ comp_unit_sp.get(), *var_info.ranges, &decl, *var_info.location, external,
+ artificial, location_is_constant_data, static_member);
if (!is_param)
m_ast->GetOrCreateVariableDecl(scope_id, var_id);
@@ -1376,9 +1364,10 @@ TypeSP SymbolFileNativePDB::CreateTypedef(PdbGlobalSymId id) {
Declaration decl;
return std::make_shared<lldb_private::Type>(
- toOpaqueUid(id), this, ConstString(udt.Name), target_type->GetByteSize(),
- nullptr, target_type->GetID(), lldb_private::Type::eEncodingIsTypedefUID,
- decl, target_type->GetForwardCompilerType(),
+ toOpaqueUid(id), this, ConstString(udt.Name),
+ target_type->GetByteSize(nullptr), nullptr, target_type->GetID(),
+ lldb_private::Type::eEncodingIsTypedefUID, decl,
+ target_type->GetForwardCompilerType(),
lldb_private::Type::ResolveState::Forward);
}
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index bf5718e11a19..61c1d77164b7 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -231,6 +231,7 @@ private:
lldb::addr_t m_obj_load_address = 0;
bool m_done_full_type_scan = false;
+ std::unique_ptr<llvm::pdb::PDBFile> m_file_up;
std::unique_ptr<PdbIndex> m_index;
std::unique_ptr<PdbAstBuilder> m_ast;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index d87926a6588f..f9c12e634140 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -550,8 +550,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
if (!ast_typedef.IsValid()) {
CompilerType target_ast_type = target_type->GetFullCompilerType();
- ast_typedef = m_ast.CreateTypedefType(
- target_ast_type, name.c_str(), m_ast.CreateDeclContext(decl_ctx), 0);
+ ast_typedef = target_ast_type.CreateTypedef(
+ name.c_str(), m_ast.CreateDeclContext(decl_ctx), 0);
if (!ast_typedef)
return nullptr;
@@ -928,7 +928,7 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
: clang::StorageClass::SC_None;
auto decl = m_ast.CreateFunctionDeclaration(
- decl_context, OptionalClangModuleID(), name.c_str(),
+ decl_context, OptionalClangModuleID(), name,
type->GetForwardCompilerType(), storage, func->hasInlineAttribute());
std::vector<clang::ParmVarDecl *> params;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index 1001514edede..befc08158cea 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -52,8 +52,6 @@
#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
#include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h"
-#include <regex>
-
using namespace lldb;
using namespace lldb_private;
using namespace llvm::pdb;
@@ -1020,8 +1018,8 @@ VariableSP SymbolFilePDB::ParseVariableForPDBData(
var_sp = std::make_shared<Variable>(
var_uid, var_name.c_str(), mangled_cstr, type_sp, scope, context_scope,
- ranges, &decl, location, is_external, is_artificial, is_static_member);
- var_sp->SetLocationIsConstantValueData(is_constant);
+ ranges, &decl, location, is_external, is_artificial, is_constant,
+ is_static_member);
m_variables.insert(std::make_pair(var_uid, var_sp));
return var_sp;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index c4a0e609aa22..3a5e02d4fb86 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -59,8 +59,6 @@ SymbolFileSymtab::SymbolFileSymtab(ObjectFileSP objfile_sp)
: SymbolFile(std::move(objfile_sp)), m_source_indexes(), m_func_indexes(),
m_code_indexes(), m_objc_class_name_to_index() {}
-SymbolFileSymtab::~SymbolFileSymtab() {}
-
uint32_t SymbolFileSymtab::CalculateAbilities() {
uint32_t abilities = 0;
if (m_objfile_sp) {
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
index 9557ebbcb272..377c41e50770 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
@@ -31,8 +31,6 @@ public:
// Constructors and Destructors
SymbolFileSymtab(lldb::ObjectFileSP objfile_sp);
- ~SymbolFileSymtab() override;
-
// Static Functions
static void Initialize();
@@ -104,10 +102,6 @@ protected:
lldb_private::Symtab::IndexCollection m_data_indexes;
lldb_private::Symtab::NameToIndexMap m_objc_class_name_to_index;
TypeMap m_objc_class_types;
-
-private:
- SymbolFileSymtab(const SymbolFileSymtab &) = delete;
- const SymbolFileSymtab &operator=(const SymbolFileSymtab &) = delete;
};
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_SYMTAB_SYMBOLFILESYMTAB_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
index 2e6fd4365021..4df5140bd7e1 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
@@ -31,9 +31,6 @@ LLDB_PLUGIN_DEFINE(SymbolVendorELF)
SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp)
: SymbolVendor(module_sp) {}
-// Destructor
-SymbolVendorELF::~SymbolVendorELF() {}
-
void SymbolVendorELF::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(), CreateInstance);
@@ -84,8 +81,7 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
if (!fspec)
fspec = obj_file->GetDebugLink().getValueOr(FileSpec());
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "SymbolVendorELF::CreateInstance (module = %s)",
+ LLDB_SCOPED_TIMERF("SymbolVendorELF::CreateInstance (module = %s)",
module_sp->GetFileSpec().GetPath().c_str());
ModuleSpec module_spec;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h
index 824906c04955..2080084a15b8 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h
@@ -17,8 +17,6 @@ public:
// Constructors and Destructors
SymbolVendorELF(const lldb::ModuleSP &module_sp);
- ~SymbolVendorELF() override;
-
// Static Functions
static void Initialize();
@@ -36,10 +34,6 @@ public:
lldb_private::ConstString GetPluginName() override;
uint32_t GetPluginVersion() override;
-
-private:
- SymbolVendorELF(const SymbolVendorELF &) = delete;
- const SymbolVendorELF &operator=(const SymbolVendorELF &) = delete;
};
#endif // LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_ELF_SYMBOLVENDORELF_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
index 1c09dabc5622..67a1ef5e4e51 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
@@ -72,8 +72,7 @@ SymbolVendorWasm::CreateInstance(const lldb::ModuleSP &module_sp,
lldb::eSectionTypeDWARFDebugInfo, true))
return nullptr;
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "SymbolVendorWasm::CreateInstance (module = %s)",
+ LLDB_SCOPED_TIMERF("SymbolVendorWasm::CreateInstance (module = %s)",
module_sp->GetFileSpec().GetPath().c_str());
ModuleSpec module_spec;
diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h
index 96e737b1be96..b212337e0549 100644
--- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h
+++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h
@@ -33,10 +33,6 @@ public:
lldb_private::ConstString GetPluginName() override;
uint32_t GetPluginVersion() override;
/// \}
-
-private:
- SymbolVendorWasm(const SymbolVendorWasm &) = delete;
- const SymbolVendorWasm &operator=(const SymbolVendorWasm &) = delete;
};
} // namespace wasm
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp
new file mode 100644
index 000000000000..e1758dfcfc41
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp
@@ -0,0 +1,73 @@
+//===-- CommandObjectTraceStartIntelPT.cpp --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectTraceStartIntelPT.h"
+
+#include "lldb/Host/OptionParser.h"
+#include "lldb/Target/Trace.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::trace_intel_pt;
+using namespace llvm;
+
+#define LLDB_OPTIONS_thread_trace_start_intel_pt
+#include "TraceIntelPTCommandOptions.inc"
+
+Status CommandObjectTraceStartIntelPT::CommandOptions::SetOptionValue(
+ uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 's': {
+ int32_t size_in_kb;
+ if (option_arg.empty() || option_arg.getAsInteger(0, size_in_kb) ||
+ size_in_kb < 0)
+ error.SetErrorStringWithFormat("invalid integer value for option '%s'",
+ option_arg.str().c_str());
+ else
+ m_size_in_kb = size_in_kb;
+ break;
+ }
+ case 'c': {
+ int32_t custom_config;
+ if (option_arg.empty() || option_arg.getAsInteger(0, custom_config) ||
+ custom_config < 0)
+ error.SetErrorStringWithFormat("invalid integer value for option '%s'",
+ option_arg.str().c_str());
+ else
+ m_custom_config = custom_config;
+ break;
+ }
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+ return error;
+}
+
+void CommandObjectTraceStartIntelPT::CommandOptions::OptionParsingStarting(
+ ExecutionContext *execution_context) {
+ m_size_in_kb = 4;
+ m_custom_config = 0;
+}
+
+llvm::ArrayRef<OptionDefinition>
+CommandObjectTraceStartIntelPT::CommandOptions::GetDefinitions() {
+ return llvm::makeArrayRef(g_thread_trace_start_intel_pt_options);
+}
+
+bool CommandObjectTraceStartIntelPT::HandleOneThread(
+ lldb::tid_t tid, CommandReturnObject &result) {
+ result.AppendMessageWithFormat(
+ "would trace tid %" PRIu64 " with size_in_kb %zu and custom_config %d\n",
+ tid, m_options.m_size_in_kb, m_options.m_custom_config);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return result.Succeeded();
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h
new file mode 100644
index 000000000000..265569c553fa
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h
@@ -0,0 +1,65 @@
+//===-- CommandObjectTraceStartIntelPT.h ----------------------*- C++ //-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTRACESTARTINTELPT_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTRACESTARTINTELPT_H
+
+#include "../../../../source/Commands/CommandObjectThreadUtil.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+
+namespace lldb_private {
+namespace trace_intel_pt {
+
+class CommandObjectTraceStartIntelPT : public CommandObjectIterateOverThreads {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override;
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+ size_t m_size_in_kb;
+ uint32_t m_custom_config;
+ };
+
+ CommandObjectTraceStartIntelPT(CommandInterpreter &interpreter)
+ : CommandObjectIterateOverThreads(
+ interpreter, "thread trace start",
+ "Start tracing one or more threads with intel-pt. "
+ "Defaults to the current thread. Thread indices can be "
+ "specified as arguments.\n Use the thread-index \"all\" to trace "
+ "all threads.",
+ "thread trace start [<thread-index> <thread-index> ...] "
+ "[<intel-pt-options>]",
+ lldb::eCommandRequiresProcess | lldb::eCommandTryTargetAPILock |
+ lldb::eCommandProcessMustBeLaunched |
+ lldb::eCommandProcessMustBePaused),
+ m_options() {}
+
+ ~CommandObjectTraceStartIntelPT() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+protected:
+ bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override;
+
+ CommandOptions m_options;
+};
+
+} // namespace trace_intel_pt
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTRACESTARTINTELPT_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
new file mode 100644
index 000000000000..6b8b06564052
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
@@ -0,0 +1,64 @@
+//===-- DecodedThread.cpp -------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "DecodedThread.h"
+
+#include "lldb/Utility/StreamString.h"
+
+using namespace lldb_private;
+using namespace lldb_private::trace_intel_pt;
+using namespace llvm;
+
+char IntelPTError::ID;
+
+IntelPTError::IntelPTError(int libipt_error_code, lldb::addr_t address)
+ : m_libipt_error_code(libipt_error_code), m_address(address) {
+ assert(libipt_error_code < 0);
+}
+
+void IntelPTError::log(llvm::raw_ostream &OS) const {
+ const char *libipt_error_message = pt_errstr(pt_errcode(m_libipt_error_code));
+ if (m_address != LLDB_INVALID_ADDRESS && m_address > 0) {
+ write_hex(OS, m_address, HexPrintStyle::PrefixLower, 18);
+ OS << " ";
+ }
+ OS << "error: " << libipt_error_message;
+}
+
+bool IntelPTInstruction::IsError() const { return (bool)m_error; }
+
+Expected<lldb::addr_t> IntelPTInstruction::GetLoadAddress() const {
+ if (IsError())
+ return ToError();
+ return m_pt_insn.ip;
+}
+
+Error IntelPTInstruction::ToError() const {
+ if (!IsError())
+ return Error::success();
+
+ if (m_error->isA<IntelPTError>())
+ return make_error<IntelPTError>(static_cast<IntelPTError &>(*m_error));
+ return make_error<StringError>(m_error->message(),
+ m_error->convertToErrorCode());
+}
+
+size_t DecodedThread::GetLastPosition() const {
+ return m_instructions.empty() ? 0 : m_instructions.size() - 1;
+}
+
+ArrayRef<IntelPTInstruction> DecodedThread::GetInstructions() const {
+ return makeArrayRef(m_instructions);
+}
+
+size_t DecodedThread::GetCursorPosition() const { return m_position; }
+
+size_t DecodedThread::SetCursorPosition(size_t new_position) {
+ m_position = std::min(new_position, GetLastPosition());
+ return m_position;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
new file mode 100644
index 000000000000..3c7e030414cb
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
@@ -0,0 +1,146 @@
+//===-- DecodedThread.h -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_DECODEDTHREAD_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_DECODEDTHREAD_H
+
+#include <vector>
+
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
+
+#include "lldb/Target/Trace.h"
+
+#include "intel-pt.h"
+
+namespace lldb_private {
+namespace trace_intel_pt {
+
+/// Class for representing a libipt decoding error.
+class IntelPTError : public llvm::ErrorInfo<IntelPTError> {
+public:
+ static char ID;
+
+ /// \param[in] libipt_error_code
+ /// Negative number returned by libipt when decoding the trace and
+ /// signaling errors.
+ ///
+ /// \param[in] address
+ /// Optional instruction address. When decoding an individual instruction,
+ /// its address might be available in the \a pt_insn object, and should be
+ /// passed to this constructor. Other errors don't have an associated
+ /// address.
+ IntelPTError(int libipt_error_code,
+ lldb::addr_t address = LLDB_INVALID_ADDRESS);
+
+ std::error_code convertToErrorCode() const override {
+ return llvm::errc::not_supported;
+ }
+
+ void log(llvm::raw_ostream &OS) const override;
+
+private:
+ int m_libipt_error_code;
+ lldb::addr_t m_address;
+};
+
+/// \class IntelPTInstruction
+/// An instruction obtained from decoding a trace. It is either an actual
+/// instruction or an error indicating a gap in the trace.
+///
+/// Gaps in the trace can come in a few flavors:
+/// - tracing gaps (e.g. tracing was paused and then resumed)
+/// - tracing errors (e.g. buffer overflow)
+/// - decoding errors (e.g. some memory region couldn't be decoded)
+/// As mentioned, any gap is represented as an error in this class.
+class IntelPTInstruction {
+public:
+ IntelPTInstruction(const pt_insn &pt_insn) : m_pt_insn(pt_insn) {}
+
+ /// Error constructor
+ ///
+ /// libipt errors should use the underlying \a IntelPTError class.
+ IntelPTInstruction(llvm::Error err) {
+ llvm::handleAllErrors(std::move(err),
+ [&](std::unique_ptr<llvm::ErrorInfoBase> info) {
+ m_error = std::move(info);
+ });
+ }
+
+ /// Check if this object represents an error (i.e. a gap).
+ ///
+ /// \return
+ /// Whether this object represents an error.
+ bool IsError() const;
+
+ /// \return
+ /// The instruction pointer address, or an \a llvm::Error if it is an
+ /// error.
+ llvm::Expected<lldb::addr_t> GetLoadAddress() const;
+
+ /// \return
+ /// An \a llvm::Error object if this class corresponds to an Error, or an
+ /// \a llvm::Error::success otherwise.
+ llvm::Error ToError() const;
+
+ IntelPTInstruction(IntelPTInstruction &&other) = default;
+
+private:
+ IntelPTInstruction(const IntelPTInstruction &other) = delete;
+ const IntelPTInstruction &operator=(const IntelPTInstruction &other) = delete;
+
+ pt_insn m_pt_insn;
+ std::unique_ptr<llvm::ErrorInfoBase> m_error;
+};
+
+/// \class DecodedThread
+/// Class holding the instructions and function call hierarchy obtained from
+/// decoding a trace, as well as a position cursor used when reverse debugging
+/// the trace.
+///
+/// Each decoded thread contains a cursor to the current position the user is
+/// stopped at. See \a Trace::GetCursorPosition for more information.
+class DecodedThread {
+public:
+ DecodedThread(std::vector<IntelPTInstruction> &&instructions)
+ : m_instructions(std::move(instructions)), m_position(GetLastPosition()) {
+ }
+
+ /// Get the instructions from the decoded trace. Some of them might indicate
+ /// errors (i.e. gaps) in the trace.
+ ///
+ /// \return
+ /// The instructions of the trace.
+ llvm::ArrayRef<IntelPTInstruction> GetInstructions() const;
+
+ /// \return
+ /// The current position of the cursor of this trace, or 0 if there are no
+ /// instructions.
+ size_t GetCursorPosition() const;
+
+ /// Change the position of the cursor of this trace. If this value is to high,
+ /// the new position will be set as the last instruction of the trace.
+ ///
+ /// \return
+ /// The effective new position.
+ size_t SetCursorPosition(size_t new_position);
+ /// \}
+
+private:
+ /// \return
+ /// The index of the last element of the trace, or 0 if empty.
+ size_t GetLastPosition() const;
+
+ std::vector<IntelPTInstruction> m_instructions;
+ size_t m_position;
+};
+
+} // namespace trace_intel_pt
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_DECODEDTHREAD_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
new file mode 100644
index 000000000000..b6e8ae808632
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
@@ -0,0 +1,215 @@
+//===-- IntelPTDecoder.cpp --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "IntelPTDecoder.h"
+
+#include "llvm/Support/MemoryBuffer.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadTrace.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::trace_intel_pt;
+using namespace llvm;
+
+/// Move the decoder forward to the next synchronization point (i.e. next PSB
+/// packet).
+///
+/// Once the decoder is at that sync. point, it can start decoding instructions.
+///
+/// \return
+/// A negative number with the libipt error if we couldn't synchronize.
+/// Otherwise, a positive number with the synchronization status will be
+/// returned.
+static int FindNextSynchronizationPoint(pt_insn_decoder &decoder) {
+ // Try to sync the decoder. If it fails, then get
+ // the decoder_offset and try to sync again from
+ // the next synchronization point. If the
+ // new_decoder_offset is same as decoder_offset
+ // then we can't move to the next synchronization
+ // point. Otherwise, keep resyncing until either
+ // end of trace stream (eos) is reached or
+ // pt_insn_sync_forward() passes.
+ int errcode = pt_insn_sync_forward(&decoder);
+
+ if (errcode != -pte_eos && errcode < 0) {
+ uint64_t decoder_offset = 0;
+ int errcode_off = pt_insn_get_offset(&decoder, &decoder_offset);
+ if (errcode_off >= 0) { // we could get the offset
+ while (true) {
+ errcode = pt_insn_sync_forward(&decoder);
+ if (errcode >= 0 || errcode == -pte_eos)
+ break;
+
+ uint64_t new_decoder_offset = 0;
+ errcode_off = pt_insn_get_offset(&decoder, &new_decoder_offset);
+ if (errcode_off < 0)
+ break; // We can't further synchronize.
+ else if (new_decoder_offset <= decoder_offset) {
+ // We tried resyncing the decoder and
+ // decoder didn't make any progress because
+ // the offset didn't change. We will not
+ // make any progress further. Hence,
+ // stopping in this situation.
+ break;
+ }
+ // We'll try again starting from a new offset.
+ decoder_offset = new_decoder_offset;
+ }
+ }
+ }
+
+ return errcode;
+}
+
+/// Before querying instructions, we need to query the events associated that
+/// instruction e.g. timing events like ptev_tick, or paging events like
+/// ptev_paging.
+///
+/// \return
+/// 0 if there were no errors processing the events, or a negative libipt
+/// error code in case of errors.
+static int ProcessPTEvents(pt_insn_decoder &decoder, int errcode) {
+ while (errcode & pts_event_pending) {
+ pt_event event;
+ errcode = pt_insn_event(&decoder, &event, sizeof(event));
+ if (errcode < 0)
+ return errcode;
+ }
+ return 0;
+};
+
+/// Decode all the instructions from a configured decoder.
+/// The decoding flow is based on
+/// https://github.com/intel/libipt/blob/master/doc/howto_libipt.md#the-instruction-flow-decode-loop
+/// but with some relaxation to allow for gaps in the trace.
+///
+/// Error codes returned by libipt while decoding are:
+/// - negative: actual errors
+/// - positive or zero: not an error, but a list of bits signaling the status of
+/// the decoder
+///
+/// \param[in] decoder
+/// A configured libipt \a pt_insn_decoder.
+///
+/// \return
+/// The decoded instructions.
+static std::vector<IntelPTInstruction>
+DecodeInstructions(pt_insn_decoder &decoder) {
+ std::vector<IntelPTInstruction> instructions;
+
+ while (true) {
+ int errcode = FindNextSynchronizationPoint(decoder);
+ if (errcode == -pte_eos)
+ break;
+
+ if (errcode < 0) {
+ instructions.emplace_back(make_error<IntelPTError>(errcode));
+ break;
+ }
+
+ // We have synchronized, so we can start decoding
+ // instructions and events.
+ while (true) {
+ errcode = ProcessPTEvents(decoder, errcode);
+ if (errcode < 0) {
+ instructions.emplace_back(make_error<IntelPTError>(errcode));
+ break;
+ }
+ pt_insn insn;
+
+ errcode = pt_insn_next(&decoder, &insn, sizeof(insn));
+ if (errcode == -pte_eos)
+ break;
+
+ if (errcode < 0) {
+ instructions.emplace_back(make_error<IntelPTError>(errcode, insn.ip));
+ break;
+ }
+
+ instructions.emplace_back(insn);
+ }
+ }
+
+ return instructions;
+}
+
+/// Callback used by libipt for reading the process memory.
+///
+/// More information can be found in
+/// https://github.com/intel/libipt/blob/master/doc/man/pt_image_set_callback.3.md
+static int ReadProcessMemory(uint8_t *buffer, size_t size,
+ const pt_asid * /* unused */, uint64_t pc,
+ void *context) {
+ Process *process = static_cast<Process *>(context);
+
+ Status error;
+ int bytes_read = process->ReadMemory(pc, buffer, size, error);
+ if (error.Fail())
+ return -pte_nomap;
+ return bytes_read;
+}
+
+static std::vector<IntelPTInstruction> makeInstructionListFromError(Error err) {
+ std::vector<IntelPTInstruction> instructions;
+ instructions.emplace_back(std::move(err));
+ return instructions;
+}
+
+static std::vector<IntelPTInstruction>
+CreateDecoderAndDecode(Process &process, const pt_cpu &pt_cpu,
+ const FileSpec &trace_file) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> trace_or_error =
+ MemoryBuffer::getFile(trace_file.GetPath());
+ if (std::error_code err = trace_or_error.getError())
+ return makeInstructionListFromError(errorCodeToError(err));
+
+ MemoryBuffer &trace = **trace_or_error;
+
+ pt_config config;
+ pt_config_init(&config);
+ config.cpu = pt_cpu;
+
+ if (int errcode = pt_cpu_errata(&config.errata, &config.cpu))
+ return makeInstructionListFromError(make_error<IntelPTError>(errcode));
+
+ // The libipt library does not modify the trace buffer, hence the following
+ // cast is safe.
+ config.begin =
+ reinterpret_cast<uint8_t *>(const_cast<char *>(trace.getBufferStart()));
+ config.end =
+ reinterpret_cast<uint8_t *>(const_cast<char *>(trace.getBufferEnd()));
+
+ pt_insn_decoder *decoder = pt_insn_alloc_decoder(&config);
+ if (!decoder)
+ return makeInstructionListFromError(make_error<IntelPTError>(-pte_nomem));
+
+ pt_image *image = pt_insn_get_image(decoder);
+
+ int errcode = pt_image_set_callback(image, ReadProcessMemory, &process);
+ assert(errcode == 0);
+ (void)errcode;
+
+ std::vector<IntelPTInstruction> instructions = DecodeInstructions(*decoder);
+
+ pt_insn_free_decoder(decoder);
+ return instructions;
+}
+
+const DecodedThread &ThreadTraceDecoder::Decode() {
+ if (!m_decoded_thread.hasValue()) {
+ m_decoded_thread = DecodedThread(
+ CreateDecoderAndDecode(*m_trace_thread->GetProcess(), m_pt_cpu,
+ m_trace_thread->GetTraceFile()));
+ }
+
+ return *m_decoded_thread;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h
new file mode 100644
index 000000000000..2e67f9bf6da7
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h
@@ -0,0 +1,52 @@
+//===-- IntelPTDecoder.h --======--------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_DECODER_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_DECODER_H
+
+#include "intel-pt.h"
+
+#include "DecodedThread.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/FileSpec.h"
+
+namespace lldb_private {
+namespace trace_intel_pt {
+
+/// \a lldb_private::ThreadTrace decoder that stores the output from decoding,
+/// avoiding recomputations, as decoding is expensive.
+class ThreadTraceDecoder {
+public:
+ /// \param[in] trace_thread
+ /// The thread whose trace file will be decoded.
+ ///
+ /// \param[in] pt_cpu
+ /// The libipt cpu used when recording the trace.
+ ThreadTraceDecoder(const std::shared_ptr<ThreadTrace> &trace_thread,
+ const pt_cpu &pt_cpu)
+ : m_trace_thread(trace_thread), m_pt_cpu(pt_cpu), m_decoded_thread() {}
+
+ /// Decode the thread and store the result internally.
+ ///
+ /// \return
+ /// A \a DecodedThread instance.
+ const DecodedThread &Decode();
+
+private:
+ ThreadTraceDecoder(const ThreadTraceDecoder &other) = delete;
+ ThreadTraceDecoder &operator=(const ThreadTraceDecoder &other) = delete;
+
+ std::shared_ptr<ThreadTrace> m_trace_thread;
+ pt_cpu m_pt_cpu;
+ llvm::Optional<DecodedThread> m_decoded_thread;
+};
+
+} // namespace trace_intel_pt
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_DECODER_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
new file mode 100644
index 000000000000..63a8b2dff4a7
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
@@ -0,0 +1,114 @@
+//===-- TraceIntelPT.cpp --------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TraceIntelPT.h"
+
+#include "CommandObjectTraceStartIntelPT.h"
+#include "TraceIntelPTSessionFileParser.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadTrace.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::trace_intel_pt;
+using namespace llvm;
+
+LLDB_PLUGIN_DEFINE(TraceIntelPT)
+
+CommandObjectSP GetStartCommand(CommandInterpreter &interpreter) {
+ return CommandObjectSP(new CommandObjectTraceStartIntelPT(interpreter));
+}
+
+void TraceIntelPT::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "Intel Processor Trace", CreateInstance,
+ TraceIntelPTSessionFileParser::GetSchema(), GetStartCommand);
+}
+
+void TraceIntelPT::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+ConstString TraceIntelPT::GetPluginNameStatic() {
+ static ConstString g_name("intel-pt");
+ return g_name;
+}
+
+StringRef TraceIntelPT::GetSchema() {
+ return TraceIntelPTSessionFileParser::GetSchema();
+}
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+
+ConstString TraceIntelPT::GetPluginName() { return GetPluginNameStatic(); }
+
+uint32_t TraceIntelPT::GetPluginVersion() { return 1; }
+
+void TraceIntelPT::Dump(Stream *s) const {}
+
+Expected<TraceSP>
+TraceIntelPT::CreateInstance(const json::Value &trace_session_file,
+ StringRef session_file_dir, Debugger &debugger) {
+ return TraceIntelPTSessionFileParser(debugger, trace_session_file,
+ session_file_dir)
+ .Parse();
+}
+
+TraceIntelPT::TraceIntelPT(
+ const pt_cpu &pt_cpu,
+ const std::vector<std::shared_ptr<ThreadTrace>> &traced_threads)
+ : m_pt_cpu(pt_cpu) {
+ for (const std::shared_ptr<ThreadTrace> &thread : traced_threads)
+ m_trace_threads.emplace(
+ std::piecewise_construct,
+ std::forward_as_tuple(thread->GetProcess()->GetID(), thread->GetID()),
+ std::forward_as_tuple(thread, pt_cpu));
+}
+
+const DecodedThread *TraceIntelPT::Decode(const Thread &thread) {
+ auto it = m_trace_threads.find(
+ std::make_pair(thread.GetProcess()->GetID(), thread.GetID()));
+ if (it == m_trace_threads.end())
+ return nullptr;
+ return &it->second.Decode();
+}
+
+size_t TraceIntelPT::GetCursorPosition(const Thread &thread) {
+ const DecodedThread *decoded_thread = Decode(thread);
+ if (!decoded_thread)
+ return 0;
+ return decoded_thread->GetCursorPosition();
+}
+
+void TraceIntelPT::TraverseInstructions(
+ const Thread &thread, size_t position, TraceDirection direction,
+ std::function<bool(size_t index, Expected<lldb::addr_t> load_addr)>
+ callback) {
+ const DecodedThread *decoded_thread = Decode(thread);
+ if (!decoded_thread)
+ return;
+
+ ArrayRef<IntelPTInstruction> instructions = decoded_thread->GetInstructions();
+
+ ssize_t delta = direction == TraceDirection::Forwards ? 1 : -1;
+ for (ssize_t i = position; i < (ssize_t)instructions.size() && i >= 0;
+ i += delta)
+ if (!callback(i, instructions[i].GetLoadAddress()))
+ break;
+}
+
+size_t TraceIntelPT::GetInstructionCount(const Thread &thread) {
+ if (const DecodedThread *decoded_thread = Decode(thread))
+ return decoded_thread->GetInstructions().size();
+ else
+ return 0;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
new file mode 100644
index 000000000000..5058e6fd32f2
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
@@ -0,0 +1,96 @@
+//===-- TraceIntelPT.h ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPT_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPT_H
+
+#include "IntelPTDecoder.h"
+#include "TraceIntelPTSessionFileParser.h"
+
+namespace lldb_private {
+namespace trace_intel_pt {
+
+class TraceIntelPT : public Trace {
+public:
+ void Dump(Stream *s) const override;
+
+ ~TraceIntelPT() override = default;
+
+ /// PluginInterface protocol
+ /// \{
+ ConstString GetPluginName() override;
+
+ static void Initialize();
+
+ static void Terminate();
+
+ /// Create an instance of this class.
+ ///
+ /// \param[in] trace_session_file
+ /// The contents of the trace session file. See \a Trace::FindPlugin.
+ ///
+ /// \param[in] session_file_dir
+ /// The path to the directory that contains the session file. It's used to
+ /// resolved relative paths in the session file.
+ ///
+ /// \param[in] debugger
+ /// The debugger instance where new Targets will be created as part of the
+ /// JSON data parsing.
+ ///
+ /// \return
+ /// A trace instance or an error in case of failures.
+ static llvm::Expected<lldb::TraceSP>
+ CreateInstance(const llvm::json::Value &trace_session_file,
+ llvm::StringRef session_file_dir, Debugger &debugger);
+
+ static ConstString GetPluginNameStatic();
+
+ uint32_t GetPluginVersion() override;
+ /// \}
+
+ llvm::StringRef GetSchema() override;
+
+ void TraverseInstructions(
+ const Thread &thread, size_t position, TraceDirection direction,
+ std::function<bool(size_t index, llvm::Expected<lldb::addr_t> load_addr)>
+ callback) override;
+
+ size_t GetInstructionCount(const Thread &thread) override;
+
+ size_t GetCursorPosition(const Thread &thread) override;
+
+private:
+ friend class TraceIntelPTSessionFileParser;
+
+ /// \param[in] trace_threads
+ /// ThreadTrace instances, which are not live-processes and whose trace
+ /// files are fixed.
+ TraceIntelPT(const pt_cpu &pt_cpu,
+ const std::vector<std::shared_ptr<ThreadTrace>> &traced_threads);
+
+ /// Decode the trace of the given thread that, i.e. recontruct the traced
+ /// instructions. That trace must be managed by this class.
+ ///
+ /// \param[in] thread
+ /// If \a thread is a \a ThreadTrace, then its internal trace file will be
+ /// decoded. Live threads are not currently supported.
+ ///
+ /// \return
+ /// A \a DecodedThread instance if decoding was successful, or a \b
+ /// nullptr if the thread's trace is not managed by this class.
+ const DecodedThread *Decode(const Thread &thread);
+
+ pt_cpu m_pt_cpu;
+ std::map<std::pair<lldb::pid_t, lldb::tid_t>, ThreadTraceDecoder>
+ m_trace_threads;
+};
+
+} // namespace trace_intel_pt
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPT_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
new file mode 100644
index 000000000000..6ffe949dbe7b
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
@@ -0,0 +1,16 @@
+include "../../../../source/Commands/OptionsBase.td"
+
+let Command = "thread trace start intel pt" in {
+ def thread_trace_start_intel_pt_size: Option<"size", "s">,
+ Group<1>,
+ Arg<"Value">,
+ Desc<"The size of the trace in KB. The kernel rounds it down to the nearest"
+ " multiple of 4. Defaults to 4.">;
+ def thread_trace_start_intel_pt_custom_config: Option<"custom-config", "c">,
+ Group<1>,
+ Arg<"Value">,
+ Desc<"Low level bitmask configuration for the kernel based on the values "
+ "in `grep -H /sys/bus/event_source/devices/intel_pt/format/*`. "
+ "See https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/perf-intel-pt.txt"
+ " for more information. Defaults to 0.">;
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
new file mode 100644
index 000000000000..beef5c3968ea
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
@@ -0,0 +1,97 @@
+//===-- TraceIntelPTSessionFileParser.cpp ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TraceIntelPTSessionFileParser.h"
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadList.h"
+#include "lldb/Target/ThreadTrace.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::trace_intel_pt;
+using namespace llvm;
+
+StringRef TraceIntelPTSessionFileParser::GetSchema() {
+ static std::string schema;
+ if (schema.empty()) {
+ schema = TraceSessionFileParser::BuildSchema(R"({
+ "type": "intel-pt",
+ "pt_cpu": {
+ "vendor": "intel" | "unknown",
+ "family": integer,
+ "model": integer,
+ "stepping": integer
+ }
+ })");
+ }
+ return schema;
+}
+
+pt_cpu TraceIntelPTSessionFileParser::ParsePTCPU(const JSONPTCPU &pt_cpu) {
+ return {pt_cpu.vendor.compare("intel") == 0 ? pcv_intel : pcv_unknown,
+ static_cast<uint16_t>(pt_cpu.family),
+ static_cast<uint8_t>(pt_cpu.model),
+ static_cast<uint8_t>(pt_cpu.stepping)};
+}
+
+TraceSP TraceIntelPTSessionFileParser::CreateTraceIntelPTInstance(
+ const pt_cpu &pt_cpu, std::vector<ParsedProcess> &parsed_processes) {
+ std::vector<ThreadTraceSP> threads;
+ for (const ParsedProcess &parsed_process : parsed_processes)
+ threads.insert(threads.end(), parsed_process.threads.begin(),
+ parsed_process.threads.end());
+
+ TraceSP trace_instance(new TraceIntelPT(pt_cpu, threads));
+ for (const ParsedProcess &parsed_process : parsed_processes)
+ parsed_process.target_sp->SetTrace(trace_instance);
+
+ return trace_instance;
+}
+
+Expected<TraceSP> TraceIntelPTSessionFileParser::Parse() {
+ json::Path::Root root("traceSession");
+ TraceSessionFileParser::JSONTraceSession<JSONTraceIntelPTSettings> session;
+ if (!json::fromJSON(m_trace_session_file, session, root))
+ return CreateJSONError(root, m_trace_session_file);
+
+ if (Expected<std::vector<ParsedProcess>> parsed_processes =
+ ParseCommonSessionFile(session))
+ return CreateTraceIntelPTInstance(ParsePTCPU(session.trace.pt_cpu),
+ *parsed_processes);
+ else
+ return parsed_processes.takeError();
+}
+
+namespace llvm {
+namespace json {
+
+bool fromJSON(const Value &value,
+ TraceIntelPTSessionFileParser::JSONPTCPU &pt_cpu, Path path) {
+ ObjectMapper o(value, path);
+ return o && o.map("vendor", pt_cpu.vendor) &&
+ o.map("family", pt_cpu.family) && o.map("model", pt_cpu.model) &&
+ o.map("stepping", pt_cpu.stepping);
+}
+
+bool fromJSON(
+ const Value &value,
+ TraceIntelPTSessionFileParser::JSONTraceIntelPTSettings &plugin_settings,
+ Path path) {
+ ObjectMapper o(value, path);
+ return o && o.map("pt_cpu", plugin_settings.pt_cpu) &&
+ fromJSON(
+ value,
+ (TraceSessionFileParser::JSONTracePluginSettings &)plugin_settings,
+ path);
+}
+
+} // namespace json
+} // namespace llvm
diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
new file mode 100644
index 000000000000..6a896de09d00
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
@@ -0,0 +1,84 @@
+//===-- TraceIntelPTSessionFileParser.h -----------------------*- C++ //-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H
+
+#include "TraceIntelPT.h"
+#include "lldb/Target/TraceSessionFileParser.h"
+
+namespace lldb_private {
+namespace trace_intel_pt {
+
+class TraceIntelPT;
+
+class TraceIntelPTSessionFileParser : public TraceSessionFileParser {
+public:
+ struct JSONPTCPU {
+ std::string vendor;
+ int64_t family;
+ int64_t model;
+ int64_t stepping;
+ };
+
+ struct JSONTraceIntelPTSettings
+ : TraceSessionFileParser::JSONTracePluginSettings {
+ JSONPTCPU pt_cpu;
+ };
+
+ /// See \a TraceSessionFileParser::TraceSessionFileParser for the description
+ /// of these fields.
+ TraceIntelPTSessionFileParser(Debugger &debugger,
+ const llvm::json::Value &trace_session_file,
+ llvm::StringRef session_file_dir)
+ : TraceSessionFileParser(debugger, session_file_dir, GetSchema()),
+ m_trace_session_file(trace_session_file) {}
+
+ /// \return
+ /// The JSON schema for the session data.
+ static llvm::StringRef GetSchema();
+
+ /// Parse the structured data trace session and create the corresponding \a
+ /// Target objects. In case of an error, no targets are created.
+ ///
+ /// \return
+ /// A \a lldb::TraceSP instance with the trace session data. In case of
+ /// errors, return a null pointer.
+ llvm::Expected<lldb::TraceSP> Parse();
+
+ lldb::TraceSP
+ CreateTraceIntelPTInstance(const pt_cpu &pt_cpu,
+ std::vector<ParsedProcess> &parsed_processes);
+
+private:
+ pt_cpu ParsePTCPU(const JSONPTCPU &pt_cpu);
+
+ const llvm::json::Value &m_trace_session_file;
+};
+
+} // namespace trace_intel_pt
+} // namespace lldb_private
+
+namespace llvm {
+namespace json {
+
+bool fromJSON(
+ const Value &value,
+ lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser::JSONPTCPU
+ &pt_cpu,
+ Path path);
+
+bool fromJSON(const Value &value,
+ lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser::
+ JSONTraceIntelPTSettings &plugin_settings,
+ Path path);
+
+} // namespace json
+} // namespace llvm
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H
diff --git a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 7491d0609e52..0218606b8937 100644
--- a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -148,10 +148,11 @@ void addOverridesForMethod(clang::CXXMethodDecl *decl) {
return;
clang::CXXBasePaths paths;
+ llvm::SmallVector<clang::NamedDecl *, 4> decls;
auto find_overridden_methods =
- [decl](const clang::CXXBaseSpecifier *specifier,
- clang::CXXBasePath &path) {
+ [&decls, decl](const clang::CXXBaseSpecifier *specifier,
+ clang::CXXBasePath &path) {
if (auto *base_record = llvm::dyn_cast<clang::CXXRecordDecl>(
specifier->getType()->getAs<clang::RecordType>()->getDecl())) {
@@ -163,6 +164,7 @@ void addOverridesForMethod(clang::CXXMethodDecl *decl) {
if (auto *baseDtorDecl = base_record->getDestructor()) {
if (baseDtorDecl->isVirtual()) {
path.Decls = baseDtorDecl;
+ decls.push_back(baseDtorDecl);
return true;
} else
return false;
@@ -175,6 +177,7 @@ void addOverridesForMethod(clang::CXXMethodDecl *decl) {
llvm::dyn_cast<clang::CXXMethodDecl>(path.Decls.front()))
if (method_decl->isVirtual() && !isOverload(decl, method_decl)) {
path.Decls = method_decl;
+ decls.push_back(method_decl);
return true;
}
}
@@ -184,7 +187,7 @@ void addOverridesForMethod(clang::CXXMethodDecl *decl) {
};
if (decl->getParent()->lookupInBases(find_overridden_methods, paths)) {
- for (auto *overridden_decl : paths.found_decls())
+ for (auto *overridden_decl : decls)
decl->addOverriddenMethod(
llvm::cast<clang::CXXMethodDecl>(overridden_decl));
}
@@ -610,7 +613,7 @@ lldb::TypeSystemSP TypeSystemClang::CreateInstance(lldb::LanguageType language,
"ASTContext for '" + module->GetFileSpec().GetPath() + "'";
return std::make_shared<TypeSystemClang>(ast_name, triple);
} else if (target && target->IsValid())
- return std::make_shared<TypeSystemClangForExpressions>(*target, triple);
+ return std::make_shared<ScratchTypeSystemClang>(*target, triple);
return lldb::TypeSystemSP();
}
@@ -1419,7 +1422,7 @@ static TemplateParameterList *CreateTemplateParameterList(
clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl(
clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
- clang::FunctionDecl *func_decl, const char *name,
+ clang::FunctionDecl *func_decl,
const TemplateParameterInfos &template_param_infos) {
// /// Create a function template node.
ASTContext &ast = getASTContext();
@@ -1657,9 +1660,9 @@ bool TypeSystemClang::FieldIsBitfield(FieldDecl *field,
if (field->isBitField()) {
Expr *bit_width_expr = field->getBitWidth();
if (bit_width_expr) {
- llvm::APSInt bit_width_apsint;
- if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, ast)) {
- bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
+ if (Optional<llvm::APSInt> bit_width_apsint =
+ bit_width_expr->getIntegerConstantExpr(ast)) {
+ bitfield_bit_size = bit_width_apsint->getLimitedValue(UINT32_MAX);
return true;
}
}
@@ -1965,11 +1968,8 @@ TypeSystemClang::GetOpaqueCompilerType(clang::ASTContext *ast,
#pragma mark Function Types
clang::DeclarationName
-TypeSystemClang::GetDeclarationName(const char *name,
+TypeSystemClang::GetDeclarationName(llvm::StringRef name,
const CompilerType &function_clang_type) {
- if (!name || !name[0])
- return clang::DeclarationName();
-
clang::OverloadedOperatorKind op_kind = clang::NUM_OVERLOADED_OPERATORS;
if (!IsOperator(name, op_kind) || op_kind == clang::NUM_OVERLOADED_OPERATORS)
return DeclarationName(&getASTContext().Idents.get(
@@ -1994,10 +1994,40 @@ TypeSystemClang::GetDeclarationName(const char *name,
return getASTContext().DeclarationNames.getCXXOperatorName(op_kind);
}
+PrintingPolicy TypeSystemClang::GetTypePrintingPolicy() {
+ clang::PrintingPolicy printing_policy(getASTContext().getPrintingPolicy());
+ printing_policy.SuppressTagKeyword = true;
+ // Inline namespaces are important for some type formatters (e.g., libc++
+ // and libstdc++ are differentiated by their inline namespaces).
+ printing_policy.SuppressInlineNamespace = false;
+ printing_policy.SuppressUnwrittenScope = false;
+ // Default arguments are also always important for type formatters. Otherwise
+ // we would need to always specify two type names for the setups where we do
+ // know the default arguments and where we don't know default arguments.
+ //
+ // For example, without this we would need to have formatters for both:
+ // std::basic_string<char>
+ // and
+ // std::basic_string<char, std::char_traits<char>, std::allocator<char> >
+ // to support setups where LLDB was able to reconstruct default arguments
+ // (and we then would have suppressed them from the type name) and also setups
+ // where LLDB wasn't able to reconstruct the default arguments.
+ printing_policy.SuppressDefaultTemplateArgs = false;
+ return printing_policy;
+}
+
+std::string TypeSystemClang::GetTypeNameForDecl(const NamedDecl *named_decl) {
+ clang::PrintingPolicy printing_policy = GetTypePrintingPolicy();
+ std::string result;
+ llvm::raw_string_ostream os(result);
+ named_decl->printQualifiedName(os, printing_policy);
+ return result;
+}
+
FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
- const char *name, const CompilerType &function_clang_type, int storage,
- bool is_inline) {
+ llvm::StringRef name, const CompilerType &function_clang_type,
+ clang::StorageClass storage, bool is_inline) {
FunctionDecl *func_decl = nullptr;
ASTContext &ast = getASTContext();
if (!decl_ctx)
@@ -2012,11 +2042,12 @@ FunctionDecl *TypeSystemClang::CreateFunctionDeclaration(
func_decl->setDeclContext(decl_ctx);
func_decl->setDeclName(declarationName);
func_decl->setType(ClangUtil::GetQualType(function_clang_type));
- func_decl->setStorageClass(static_cast<clang::StorageClass>(storage));
+ func_decl->setStorageClass(storage);
func_decl->setInlineSpecified(is_inline);
func_decl->setHasWrittenPrototype(hasWrittenPrototype);
- func_decl->setConstexprKind(isConstexprSpecified ? CSK_constexpr
- : CSK_unspecified);
+ func_decl->setConstexprKind(isConstexprSpecified
+ ? ConstexprSpecKind::Constexpr
+ : ConstexprSpecKind::Unspecified);
SetOwningModule(func_decl, owning_module);
if (func_decl)
decl_ctx->addDecl(func_decl);
@@ -2499,6 +2530,8 @@ RemoveWrappingTypes(QualType type, ArrayRef<clang::Type::TypeClass> mask = {}) {
case clang::Type::Decltype:
case clang::Type::Elaborated:
case clang::Type::Paren:
+ case clang::Type::SubstTemplateTypeParm:
+ case clang::Type::TemplateSpecialization:
case clang::Type::Typedef:
case clang::Type::TypeOf:
case clang::Type::TypeOfExpr:
@@ -2882,20 +2915,11 @@ bool TypeSystemClang::IsCStringType(lldb::opaque_compiler_type_t type,
return false;
}
-bool TypeSystemClang::IsFunctionType(lldb::opaque_compiler_type_t type,
- bool *is_variadic_ptr) {
+bool TypeSystemClang::IsFunctionType(lldb::opaque_compiler_type_t type) {
if (type) {
clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
if (qual_type->isFunctionType()) {
- if (is_variadic_ptr) {
- const clang::FunctionProtoType *function_proto_type =
- llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
- if (function_proto_type)
- *is_variadic_ptr = function_proto_type->isVariadic();
- else
- *is_variadic_ptr = false;
- }
return true;
}
@@ -2908,8 +2932,8 @@ bool TypeSystemClang::IsFunctionType(lldb::opaque_compiler_type_t type,
const clang::ReferenceType *reference_type =
llvm::cast<clang::ReferenceType>(qual_type.getTypePtr());
if (reference_type)
- return IsFunctionType(reference_type->getPointeeType().getAsOpaquePtr(),
- nullptr);
+ return IsFunctionType(
+ reference_type->getPointeeType().getAsOpaquePtr());
} break;
}
}
@@ -3123,6 +3147,20 @@ bool TypeSystemClang::IsEnumerationType(lldb::opaque_compiler_type_t type,
return false;
}
+bool TypeSystemClang::IsScopedEnumerationType(
+ lldb::opaque_compiler_type_t type) {
+ if (type) {
+ const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(
+ GetCanonicalQualType(type)->getCanonicalTypeInternal());
+
+ if (enum_type) {
+ return enum_type->isScopedEnumeralType();
+ }
+ }
+
+ return false;
+}
+
bool TypeSystemClang::IsPointerType(lldb::opaque_compiler_type_t type,
CompilerType *pointee_type) {
if (type) {
@@ -3640,15 +3678,23 @@ ConstString TypeSystemClang::GetTypeName(lldb::opaque_compiler_type_t type) {
clang::QualType qual_type(GetQualType(type));
+ // Remove certain type sugar from the name. Sugar such as elaborated types
+ // or template types which only serve to improve diagnostics shouldn't
+ // act as their own types from the user's perspective (e.g., formatter
+ // shouldn't format a variable differently depending on how the ser has
+ // specified the type. '::Type' and 'Type' should behave the same).
+ // Typedefs and atomic derived types are not removed as they are actually
+ // useful for identifiying specific types.
+ qual_type = RemoveWrappingTypes(qual_type,
+ {clang::Type::Typedef, clang::Type::Atomic});
+
// For a typedef just return the qualified name.
if (const auto *typedef_type = qual_type->getAs<clang::TypedefType>()) {
const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
- return ConstString(typedef_decl->getQualifiedNameAsString());
+ return ConstString(GetTypeNameForDecl(typedef_decl));
}
- clang::PrintingPolicy printing_policy(getASTContext().getPrintingPolicy());
- printing_policy.SuppressTagKeyword = true;
- return ConstString(qual_type.getAsString(printing_policy));
+ return ConstString(qual_type.getAsString(GetTypePrintingPolicy()));
}
ConstString
@@ -3661,6 +3707,7 @@ TypeSystemClang::GetDisplayTypeName(lldb::opaque_compiler_type_t type) {
printing_policy.SuppressTagKeyword = true;
printing_policy.SuppressScope = false;
printing_policy.SuppressUnwrittenScope = true;
+ printing_policy.SuppressInlineNamespace = true;
return ConstString(qual_type.getAsString(printing_policy));
}
@@ -4088,7 +4135,7 @@ unsigned TypeSystemClang::GetTypeQualifiers(lldb::opaque_compiler_type_t type) {
CompilerType
TypeSystemClang::GetArrayElementType(lldb::opaque_compiler_type_t type,
- uint64_t *stride) {
+ ExecutionContextScope *exe_scope) {
if (type) {
clang::QualType qual_type(GetQualType(type));
@@ -4098,14 +4145,7 @@ TypeSystemClang::GetArrayElementType(lldb::opaque_compiler_type_t type,
if (!array_eletype)
return CompilerType();
- CompilerType element_type = GetType(clang::QualType(array_eletype, 0));
-
- // TODO: the real stride will be >= this value.. find the real one!
- if (stride)
- if (Optional<uint64_t> size = element_type.GetByteSize(nullptr))
- *stride = *size;
-
- return element_type;
+ return GetType(clang::QualType(array_eletype, 0));
}
return CompilerType();
}
@@ -4155,6 +4195,13 @@ TypeSystemClang::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
return CompilerType();
}
+CompilerType
+TypeSystemClang::GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) {
+ if (type)
+ return GetEnumerationIntegerType(GetType(GetCanonicalQualType(type)));
+ return CompilerType();
+}
+
int TypeSystemClang::GetFunctionArgumentCount(
lldb::opaque_compiler_type_t type) {
if (type) {
@@ -4376,39 +4423,6 @@ TypeSystemClang::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
return CompilerType();
}
-CompilerType TypeSystemClang::CreateTypedefType(
- const CompilerType &type, const char *typedef_name,
- const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) {
- if (type && typedef_name && typedef_name[0]) {
- TypeSystemClang *ast =
- llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
- if (!ast)
- return CompilerType();
- clang::ASTContext &clang_ast = ast->getASTContext();
- clang::QualType qual_type(ClangUtil::GetQualType(type));
-
- clang::DeclContext *decl_ctx =
- TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx);
- if (!decl_ctx)
- decl_ctx = ast->getASTContext().getTranslationUnitDecl();
-
- clang::TypedefDecl *decl =
- clang::TypedefDecl::CreateDeserialized(clang_ast, 0);
- decl->setDeclContext(decl_ctx);
- decl->setDeclName(&clang_ast.Idents.get(typedef_name));
- decl->setTypeSourceInfo(clang_ast.getTrivialTypeSourceInfo(qual_type));
-
- SetOwningModule(decl, TypePayloadClang(payload).GetOwningModule());
- decl->setAccess(clang::AS_public); // TODO respect proper access specifier
-
- decl_ctx->addDecl(decl);
-
- // Get a uniqued clang::QualType for the typedef decl type
- return ast->GetType(clang_ast.getTypedefType(decl));
- }
- return CompilerType();
-}
-
CompilerType
TypeSystemClang::GetPointeeType(lldb::opaque_compiler_type_t type) {
if (type) {
@@ -4490,7 +4504,7 @@ TypeSystemClang::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
CompilerType TypeSystemClang::CreateTypedef(
lldb::opaque_compiler_type_t type, const char *typedef_name,
const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) {
- if (type) {
+ if (type && typedef_name && typedef_name[0]) {
clang::ASTContext &clang_ast = getASTContext();
clang::QualType qual_type(GetQualType(type));
@@ -4499,10 +4513,12 @@ CompilerType TypeSystemClang::CreateTypedef(
if (!decl_ctx)
decl_ctx = getASTContext().getTranslationUnitDecl();
- clang::TypedefDecl *decl = clang::TypedefDecl::Create(
- clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
- &clang_ast.Idents.get(typedef_name),
- clang_ast.getTrivialTypeSourceInfo(qual_type));
+ clang::TypedefDecl *decl =
+ clang::TypedefDecl::CreateDeserialized(clang_ast, 0);
+ decl->setDeclContext(decl_ctx);
+ decl->setDeclName(&clang_ast.Idents.get(typedef_name));
+ decl->setTypeSourceInfo(clang_ast.getTrivialTypeSourceInfo(qual_type));
+ decl_ctx->addDecl(decl);
SetOwningModule(decl, TypePayloadClang(payload).GetOwningModule());
clang::TagDecl *tdecl = nullptr;
@@ -4816,6 +4832,12 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type,
case clang::BuiltinType::OCLIntelSubgroupAVCImeDualRefStreamin:
break;
+ // PowerPC -- Matrix Multiply Assist
+ case clang::BuiltinType::VectorPair:
+ case clang::BuiltinType::VectorQuad:
+ break;
+
+ // ARM -- Scalable Vector Extension
case clang::BuiltinType::SveBool:
case clang::BuiltinType::SveInt8:
case clang::BuiltinType::SveInt8x2:
@@ -6514,8 +6536,10 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(
if (cxx_record_decl->lookupInBases(
[decl_name](const clang::CXXBaseSpecifier *specifier,
clang::CXXBasePath &path) {
- return clang::CXXRecordDecl::FindOrdinaryMember(
- specifier, path, decl_name);
+ path.Decls =
+ specifier->getType()->getAsCXXRecordDecl()->lookup(
+ decl_name);
+ return !path.Decls.empty();
},
paths)) {
clang::CXXBasePaths::const_paths_iterator path,
@@ -7399,7 +7423,7 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
cxx_dtor_decl->setType(method_qual_type);
cxx_dtor_decl->setImplicit(is_artificial);
cxx_dtor_decl->setInlineSpecified(is_inline);
- cxx_dtor_decl->setConstexprKind(CSK_unspecified);
+ cxx_dtor_decl->setConstexprKind(ConstexprSpecKind::Unspecified);
cxx_method_decl = cxx_dtor_decl;
} else if (decl_name == cxx_record_decl->getDeclName()) {
cxx_ctor_decl = clang::CXXConstructorDecl::CreateDeserialized(
@@ -7411,7 +7435,7 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
cxx_ctor_decl->setType(method_qual_type);
cxx_ctor_decl->setImplicit(is_artificial);
cxx_ctor_decl->setInlineSpecified(is_inline);
- cxx_ctor_decl->setConstexprKind(CSK_unspecified);
+ cxx_ctor_decl->setConstexprKind(ConstexprSpecKind::Unspecified);
cxx_ctor_decl->setNumCtorInitializers(0);
cxx_ctor_decl->setExplicitSpecifier(explicit_spec);
cxx_method_decl = cxx_ctor_decl;
@@ -7437,7 +7461,7 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
cxx_method_decl->setType(method_qual_type);
cxx_method_decl->setStorageClass(SC);
cxx_method_decl->setInlineSpecified(is_inline);
- cxx_method_decl->setConstexprKind(CSK_unspecified);
+ cxx_method_decl->setConstexprKind(ConstexprSpecKind::Unspecified);
} else if (num_params == 0) {
// Conversion operators don't take params...
auto *cxx_conversion_decl =
@@ -7450,7 +7474,7 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
cxx_conversion_decl->setType(method_qual_type);
cxx_conversion_decl->setInlineSpecified(is_inline);
cxx_conversion_decl->setExplicitSpecifier(explicit_spec);
- cxx_conversion_decl->setConstexprKind(CSK_unspecified);
+ cxx_conversion_decl->setConstexprKind(ConstexprSpecKind::Unspecified);
cxx_method_decl = cxx_conversion_decl;
}
}
@@ -7463,7 +7487,7 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
cxx_method_decl->setType(method_qual_type);
cxx_method_decl->setInlineSpecified(is_inline);
cxx_method_decl->setStorageClass(SC);
- cxx_method_decl->setConstexprKind(CSK_unspecified);
+ cxx_method_decl->setConstexprKind(ConstexprSpecKind::Unspecified);
}
}
SetMemberOwningModule(cxx_method_decl, cxx_record_decl);
@@ -8925,8 +8949,7 @@ void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type,
if (level == eDescriptionLevelVerbose)
typedef_decl->dump(llvm_ostrm);
else {
- std::string clang_typedef_name(
- typedef_decl->getQualifiedNameAsString());
+ std::string clang_typedef_name(GetTypeNameForDecl(typedef_decl));
if (!clang_typedef_name.empty()) {
s->PutCString("typedef ");
s->PutCString(clang_typedef_name);
@@ -9407,8 +9430,7 @@ TypeSystemClang::DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) {
clang::NamedDecl *named_decl =
llvm::dyn_cast<clang::NamedDecl>((clang::DeclContext *)opaque_decl_ctx);
if (named_decl)
- return ConstString(
- llvm::StringRef(named_decl->getQualifiedNameAsString()));
+ return ConstString(GetTypeNameForDecl(named_decl));
}
return ConstString();
}
@@ -9529,29 +9551,77 @@ TypeSystemClang::DeclContextGetTypeSystemClang(const CompilerDeclContext &dc) {
return nullptr;
}
-TypeSystemClangForExpressions::TypeSystemClangForExpressions(
- Target &target, llvm::Triple triple)
- : TypeSystemClang("scratch ASTContext", triple),
+namespace {
+/// A specialized scratch AST used within ScratchTypeSystemClang.
+/// These are the ASTs backing the different IsolatedASTKinds. They behave
+/// like a normal ScratchTypeSystemClang but they don't own their own
+/// persistent storage or target reference.
+class SpecializedScratchAST : public TypeSystemClang {
+public:
+ /// \param name The display name of the TypeSystemClang instance.
+ /// \param triple The triple used for the TypeSystemClang instance.
+ /// \param ast_source The ClangASTSource that should be used to complete
+ /// type information.
+ SpecializedScratchAST(llvm::StringRef name, llvm::Triple triple,
+ std::unique_ptr<ClangASTSource> ast_source)
+ : TypeSystemClang(name, triple),
+ m_scratch_ast_source_up(std::move(ast_source)) {
+ // Setup the ClangASTSource to complete this AST.
+ m_scratch_ast_source_up->InstallASTContext(*this);
+ llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
+ m_scratch_ast_source_up->CreateProxy());
+ SetExternalSource(proxy_ast_source);
+ }
+
+ /// The ExternalASTSource that performs lookups and completes types.
+ std::unique_ptr<ClangASTSource> m_scratch_ast_source_up;
+};
+} // namespace
+
+char ScratchTypeSystemClang::ID;
+const llvm::NoneType ScratchTypeSystemClang::DefaultAST = llvm::None;
+
+ScratchTypeSystemClang::ScratchTypeSystemClang(Target &target,
+ llvm::Triple triple)
+ : TypeSystemClang("scratch ASTContext", triple), m_triple(triple),
m_target_wp(target.shared_from_this()),
m_persistent_variables(new ClangPersistentVariables) {
- m_scratch_ast_source_up = std::make_unique<ClangASTSource>(
- target.shared_from_this(), m_persistent_variables->GetClangASTImporter());
+ m_scratch_ast_source_up = CreateASTSource();
m_scratch_ast_source_up->InstallASTContext(*this);
llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
m_scratch_ast_source_up->CreateProxy());
SetExternalSource(proxy_ast_source);
}
-void TypeSystemClangForExpressions::Finalize() {
+void ScratchTypeSystemClang::Finalize() {
TypeSystemClang::Finalize();
m_scratch_ast_source_up.reset();
}
-UserExpression *TypeSystemClangForExpressions::GetUserExpression(
+TypeSystemClang *
+ScratchTypeSystemClang::GetForTarget(Target &target,
+ llvm::Optional<IsolatedASTKind> ast_kind,
+ bool create_on_demand) {
+ auto type_system_or_err = target.GetScratchTypeSystemForLanguage(
+ lldb::eLanguageTypeC, create_on_demand);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET),
+ std::move(err), "Couldn't get scratch TypeSystemClang");
+ return nullptr;
+ }
+ ScratchTypeSystemClang &scratch_ast =
+ llvm::cast<ScratchTypeSystemClang>(type_system_or_err.get());
+ // If no dedicated sub-AST was requested, just return the main AST.
+ if (ast_kind == DefaultAST)
+ return &scratch_ast;
+ // Search the sub-ASTs.
+ return &scratch_ast.GetIsolatedAST(*ast_kind);
+}
+
+UserExpression *ScratchTypeSystemClang::GetUserExpression(
llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
Expression::ResultType desired_type,
- const EvaluateExpressionOptions &options,
- ValueObject *ctx_obj) {
+ const EvaluateExpressionOptions &options, ValueObject *ctx_obj) {
TargetSP target_sp = m_target_wp.lock();
if (!target_sp)
return nullptr;
@@ -9560,7 +9630,7 @@ UserExpression *TypeSystemClangForExpressions::GetUserExpression(
desired_type, options, ctx_obj);
}
-FunctionCaller *TypeSystemClangForExpressions::GetFunctionCaller(
+FunctionCaller *ScratchTypeSystemClang::GetFunctionCaller(
const CompilerType &return_type, const Address &function_address,
const ValueList &arg_value_list, const char *name) {
TargetSP target_sp = m_target_wp.lock();
@@ -9575,17 +9645,56 @@ FunctionCaller *TypeSystemClangForExpressions::GetFunctionCaller(
arg_value_list, name);
}
-UtilityFunction *
-TypeSystemClangForExpressions::GetUtilityFunction(const char *text,
- const char *name) {
+std::unique_ptr<UtilityFunction>
+ScratchTypeSystemClang::CreateUtilityFunction(std::string text,
+ std::string name) {
TargetSP target_sp = m_target_wp.lock();
if (!target_sp)
- return nullptr;
+ return {};
- return new ClangUtilityFunction(*target_sp.get(), text, name);
+ return std::make_unique<ClangUtilityFunction>(
+ *target_sp.get(), std::move(text), std::move(name));
}
PersistentExpressionState *
-TypeSystemClangForExpressions::GetPersistentExpressionState() {
+ScratchTypeSystemClang::GetPersistentExpressionState() {
return m_persistent_variables.get();
}
+
+void ScratchTypeSystemClang::ForgetSource(ASTContext *src_ctx,
+ ClangASTImporter &importer) {
+ // Remove it as a source from the main AST.
+ importer.ForgetSource(&getASTContext(), src_ctx);
+ // Remove it as a source from all created sub-ASTs.
+ for (const auto &a : m_isolated_asts)
+ importer.ForgetSource(&a.second->getASTContext(), src_ctx);
+}
+
+std::unique_ptr<ClangASTSource> ScratchTypeSystemClang::CreateASTSource() {
+ return std::make_unique<ClangASTSource>(
+ m_target_wp.lock()->shared_from_this(),
+ m_persistent_variables->GetClangASTImporter());
+}
+
+static llvm::StringRef
+GetSpecializedASTName(ScratchTypeSystemClang::IsolatedASTKind feature) {
+ switch (feature) {
+ case ScratchTypeSystemClang::IsolatedASTKind::CppModules:
+ return "scratch ASTContext for C++ module types";
+ }
+ llvm_unreachable("Unimplemented ASTFeature kind?");
+}
+
+TypeSystemClang &ScratchTypeSystemClang::GetIsolatedAST(
+ ScratchTypeSystemClang::IsolatedASTKind feature) {
+ auto found_ast = m_isolated_asts.find(feature);
+ if (found_ast != m_isolated_asts.end())
+ return *found_ast->second;
+
+ // Couldn't find the requested sub-AST, so create it now.
+ std::unique_ptr<TypeSystemClang> new_ast;
+ new_ast.reset(new SpecializedScratchAST(GetSpecializedASTName(feature),
+ m_triple, CreateASTSource()));
+ m_isolated_asts[feature] = std::move(new_ast);
+ return *m_isolated_asts[feature];
+}
diff --git a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index 659d48812353..d1d876d05a6b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -156,18 +156,6 @@ public:
static TypeSystemClang *GetASTContext(clang::ASTContext *ast_ctx);
- static TypeSystemClang *GetScratch(Target &target,
- bool create_on_demand = true) {
- auto type_system_or_err = target.GetScratchTypeSystemForLanguage(
- lldb::eLanguageTypeC, create_on_demand);
- if (auto err = type_system_or_err.takeError()) {
- LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET),
- std::move(err), "Couldn't get scratch TypeSystemClang");
- return nullptr;
- }
- return llvm::dyn_cast<TypeSystemClang>(&type_system_or_err.get());
- }
-
/// Returns the display name of this TypeSystemClang that indicates what
/// purpose it serves in LLDB. Used for example in logs.
llvm::StringRef getDisplayName() const { return m_display_name; }
@@ -332,10 +320,11 @@ public:
class TemplateParameterInfos {
public:
bool IsValid() const {
- if (args.empty())
+ // Having a pack name but no packed args doesn't make sense, so mark
+ // these template parameters as invalid.
+ if (pack_name && !packed_args)
return false;
return args.size() == names.size() &&
- ((bool)pack_name == (bool)packed_args) &&
(!packed_args || !packed_args->packed_args);
}
@@ -346,11 +335,9 @@ public:
std::unique_ptr<TemplateParameterInfos> packed_args;
};
- clang::FunctionTemplateDecl *
- CreateFunctionTemplateDecl(clang::DeclContext *decl_ctx,
- OptionalClangModuleID owning_module,
- clang::FunctionDecl *func_decl, const char *name,
- const TemplateParameterInfos &infos);
+ clang::FunctionTemplateDecl *CreateFunctionTemplateDecl(
+ clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+ clang::FunctionDecl *func_decl, const TemplateParameterInfos &infos);
void CreateFunctionTemplateSpecializationInfo(
clang::FunctionDecl *func_decl, clang::FunctionTemplateDecl *Template,
@@ -410,11 +397,10 @@ public:
// Function Types
- clang::FunctionDecl *
- CreateFunctionDeclaration(clang::DeclContext *decl_ctx,
- OptionalClangModuleID owning_module,
- const char *name, const CompilerType &function_Type,
- int storage, bool is_inline);
+ clang::FunctionDecl *CreateFunctionDeclaration(
+ clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module,
+ llvm::StringRef name, const CompilerType &function_Type,
+ clang::StorageClass storage, bool is_inline);
CompilerType CreateFunctionType(const CompilerType &result_type,
const CompilerType *args, unsigned num_args,
@@ -594,8 +580,7 @@ public:
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) override;
+ bool IsFunctionType(lldb::opaque_compiler_type_t type) override;
uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
CompilerType *base_type_ptr) override;
@@ -617,6 +602,8 @@ public:
bool IsEnumerationType(lldb::opaque_compiler_type_t type,
bool &is_signed) override;
+ bool IsScopedEnumerationType(lldb::opaque_compiler_type_t type) override;
+
static bool IsObjCClassType(const CompilerType &type);
static bool IsObjCClassTypeAndHasIVars(const CompilerType &type,
@@ -682,16 +669,8 @@ public:
// Creating related types
- /// Using the current type, create a new typedef to that type using
- /// "typedef_name" as the name and "decl_ctx" as the decl context.
- /// \param payload is an opaque TypePayloadClang.
- static CompilerType
- CreateTypedefType(const CompilerType &type, const char *typedef_name,
- const CompilerDeclContext &compiler_decl_ctx,
- uint32_t opaque_payload);
-
CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type,
- uint64_t *stride) override;
+ ExecutionContextScope *exe_scope) override;
CompilerType GetArrayType(lldb::opaque_compiler_type_t type,
uint64_t size) override;
@@ -701,6 +680,9 @@ public:
CompilerType
GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override;
+ CompilerType
+ GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) override;
+
// Returns -1 if this isn't a function of if the function doesn't have a
// prototype Returns a value >= 0 if there is a prototype.
int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override;
@@ -737,6 +719,9 @@ public:
CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type) override;
+ /// Using the current type, create a new typedef to that type using
+ /// "typedef_name" as the name and "decl_ctx" as the decl context.
+ /// \param opaque_payload is an opaque TypePayloadClang.
CompilerType CreateTypedef(lldb::opaque_compiler_type_t type,
const char *name,
const CompilerDeclContext &decl_ctx,
@@ -1057,7 +1042,8 @@ public:
}
clang::DeclarationName
- GetDeclarationName(const char *name, const CompilerType &function_clang_type);
+ GetDeclarationName(llvm::StringRef name,
+ const CompilerType &function_clang_type);
clang::LangOptions *GetLangOpts() const {
return m_language_options_up.get();
@@ -1067,6 +1053,13 @@ public:
}
private:
+ /// Returns the PrintingPolicy used when generating the internal type names.
+ /// These type names are mostly used for the formatter selection.
+ clang::PrintingPolicy GetTypePrintingPolicy();
+ /// Returns the internal type name for the given NamedDecl using the
+ /// type printing policy.
+ std::string GetTypeNameForDecl(const clang::NamedDecl *named_decl);
+
const clang::ClassTemplateSpecializationDecl *
GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type);
@@ -1120,14 +1113,71 @@ private:
/// The TypeSystemClang instance used for the scratch ASTContext in a
/// lldb::Target.
-class TypeSystemClangForExpressions : public TypeSystemClang {
+class ScratchTypeSystemClang : public TypeSystemClang {
+ /// LLVM RTTI support
+ static char ID;
+
public:
- TypeSystemClangForExpressions(Target &target, llvm::Triple triple);
+ ScratchTypeSystemClang(Target &target, llvm::Triple triple);
- ~TypeSystemClangForExpressions() override = default;
+ ~ScratchTypeSystemClang() override = default;
void Finalize() override;
+ /// The different kinds of isolated ASTs within the scratch TypeSystem.
+ ///
+ /// These ASTs are isolated from the main scratch AST and are each
+ /// dedicated to a special language option/feature that makes the contained
+ /// AST nodes incompatible with other AST nodes.
+ enum IsolatedASTKind {
+ /// The isolated AST for declarations/types from expressions that imported
+ /// type information from a C++ module. The templates from a C++ module
+ /// often conflict with the templates we generate from debug information,
+ /// so we put these types in their own AST.
+ CppModules
+ };
+
+ /// Alias for requesting the default scratch TypeSystemClang in GetForTarget.
+ // This isn't constexpr as gtest/llvm::Optional comparison logic is trying
+ // to get the address of this for pretty-printing.
+ static const llvm::NoneType DefaultAST;
+
+ /// Infers the appropriate sub-AST from Clang's LangOptions.
+ static llvm::Optional<IsolatedASTKind>
+ InferIsolatedASTKindFromLangOpts(const clang::LangOptions &l) {
+ // If modules are activated we want the dedicated C++ module AST.
+ // See IsolatedASTKind::CppModules for more info.
+ if (l.Modules)
+ return IsolatedASTKind::CppModules;
+ return DefaultAST;
+ }
+
+ /// Returns the scratch TypeSystemClang for the given target.
+ /// \param target The Target which scratch TypeSystemClang should be returned.
+ /// \param ast_kind Allows requesting a specific sub-AST instead of the
+ /// default scratch AST. See also `IsolatedASTKind`.
+ /// \param create_on_demand If the scratch TypeSystemClang instance can be
+ /// created by this call if it doesn't exist yet. If it doesn't exist yet and
+ /// this parameter is false, this function returns a nullptr.
+ /// \return The scratch type system of the target or a nullptr in case an
+ /// error occurred.
+ static TypeSystemClang *
+ GetForTarget(Target &target,
+ llvm::Optional<IsolatedASTKind> ast_kind = DefaultAST,
+ bool create_on_demand = true);
+
+ /// Returns the scratch TypeSystemClang for the given target. The returned
+ /// TypeSystemClang will be the scratch AST or a sub-AST, depending on which
+ /// fits best to the passed LangOptions.
+ /// \param target The Target which scratch TypeSystemClang should be returned.
+ /// \param lang_opts The LangOptions of a clang ASTContext that the caller
+ /// wants to export type information from. This is used to
+ /// find the best matching sub-AST that will be returned.
+ static TypeSystemClang *GetForTarget(Target &target,
+ const clang::LangOptions &lang_opts) {
+ return GetForTarget(target, InferIsolatedASTKindFromLangOpts(lang_opts));
+ }
+
UserExpression *
GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix,
lldb::LanguageType language,
@@ -1140,16 +1190,48 @@ public:
const ValueList &arg_value_list,
const char *name) override;
- UtilityFunction *GetUtilityFunction(const char *text,
- const char *name) override;
+ std::unique_ptr<UtilityFunction>
+ CreateUtilityFunction(std::string text, std::string name) override;
PersistentExpressionState *GetPersistentExpressionState() override;
+
+ /// Unregisters the given ASTContext as a source from the scratch AST (and
+ /// all sub-ASTs).
+ /// \see ClangASTImporter::ForgetSource
+ void ForgetSource(clang::ASTContext *src_ctx, ClangASTImporter &importer);
+
+ // llvm casting support
+ bool isA(const void *ClassID) const override {
+ return ClassID == &ID || TypeSystemClang::isA(ClassID);
+ }
+ static bool classof(const TypeSystem *ts) { return ts->isA(&ID); }
+
private:
+ std::unique_ptr<ClangASTSource> CreateASTSource();
+ /// Returns the requested sub-AST.
+ /// Will lazily create the sub-AST if it hasn't been created before.
+ TypeSystemClang &GetIsolatedAST(IsolatedASTKind feature);
+
+ /// The target triple.
+ /// This was potentially adjusted and might not be identical to the triple
+ /// of `m_target_wp`.
+ llvm::Triple m_triple;
lldb::TargetWP m_target_wp;
- std::unique_ptr<ClangPersistentVariables>
- m_persistent_variables; // These are the persistent variables associated
- // with this process for the expression parser
+ /// The persistent variables associated with this process for the expression
+ /// parser.
+ std::unique_ptr<ClangPersistentVariables> m_persistent_variables;
+ /// The ExternalASTSource that performs lookups and completes minimally
+ /// imported types.
std::unique_ptr<ClangASTSource> m_scratch_ast_source_up;
+
+ // FIXME: GCC 5.x doesn't support enum as map keys.
+ typedef int IsolatedASTKey;
+
+ /// Map from IsolatedASTKind to their actual TypeSystemClang instance.
+ /// This map is lazily filled with sub-ASTs and should be accessed via
+ /// `GetSubAST` (which lazily fills this map).
+ std::unordered_map<IsolatedASTKey, std::unique_ptr<TypeSystemClang>>
+ m_isolated_asts;
};
} // namespace lldb_private
diff --git a/contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp b/contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp
index 0c67bf5b702a..822f0df4da37 100644
--- a/contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp
+++ b/contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp
@@ -75,8 +75,7 @@ void CompileUnit::ForeachFunction(
lldb::FunctionSP CompileUnit::FindFunction(
llvm::function_ref<bool(const FunctionSP &)> matching_lambda) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "CompileUnit::FindFunction");
+ LLDB_SCOPED_TIMER();
lldb::ModuleSP module = CalculateSymbolContextModule();
diff --git a/contrib/llvm-project/lldb/source/Symbol/CompilerType.cpp b/contrib/llvm-project/lldb/source/Symbol/CompilerType.cpp
index f819c9f8ce23..4f0c3b366af5 100644
--- a/contrib/llvm-project/lldb/source/Symbol/CompilerType.cpp
+++ b/contrib/llvm-project/lldb/source/Symbol/CompilerType.cpp
@@ -40,6 +40,12 @@ bool CompilerType::IsAnonymousType() const {
return false;
}
+bool CompilerType::IsScopedEnumerationType() const {
+ if (IsValid())
+ return m_type_system->IsScopedEnumerationType(m_type);
+ return false;
+}
+
bool CompilerType::IsArrayType(CompilerType *element_type_ptr, uint64_t *size,
bool *is_incomplete) const {
if (IsValid())
@@ -92,9 +98,9 @@ bool CompilerType::IsCStringType(uint32_t &length) const {
return false;
}
-bool CompilerType::IsFunctionType(bool *is_variadic_ptr) const {
+bool CompilerType::IsFunctionType() const {
if (IsValid())
- return m_type_system->IsFunctionType(m_type, is_variadic_ptr);
+ return m_type_system->IsFunctionType(m_type);
return false;
}
@@ -317,9 +323,10 @@ unsigned CompilerType::GetTypeQualifiers() const {
// Creating related types
-CompilerType CompilerType::GetArrayElementType(uint64_t *stride) const {
+CompilerType
+CompilerType::GetArrayElementType(ExecutionContextScope *exe_scope) const {
if (IsValid()) {
- return m_type_system->GetArrayElementType(m_type, stride);
+ return m_type_system->GetArrayElementType(m_type, exe_scope);
}
return CompilerType();
}
@@ -343,6 +350,12 @@ CompilerType CompilerType::GetFullyUnqualifiedType() const {
return CompilerType();
}
+CompilerType CompilerType::GetEnumerationIntegerType() const {
+ if (IsValid())
+ return m_type_system->GetEnumerationIntegerType(m_type);
+ return CompilerType();
+}
+
int CompilerType::GetFunctionArgumentCount() const {
if (IsValid()) {
return m_type_system->GetFunctionArgumentCount(m_type);
@@ -766,8 +779,8 @@ LLVM_DUMP_METHOD void CompilerType::dump() const {
bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data,
lldb::offset_t data_byte_offset,
- size_t data_byte_size,
- Scalar &value) const {
+ size_t data_byte_size, Scalar &value,
+ ExecutionContextScope *exe_scope) const {
if (!IsValid())
return false;
@@ -780,7 +793,7 @@ bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data,
if (encoding == lldb::eEncodingInvalid || count != 1)
return false;
- llvm::Optional<uint64_t> byte_size = GetByteSize(nullptr);
+ llvm::Optional<uint64_t> byte_size = GetByteSize(exe_scope);
if (!byte_size)
return false;
lldb::offset_t offset = data_byte_offset;
diff --git a/contrib/llvm-project/lldb/source/Symbol/DWARFCallFrameInfo.cpp b/contrib/llvm-project/lldb/source/Symbol/DWARFCallFrameInfo.cpp
index 3111c33c7108..f0dce8f4793a 100644
--- a/contrib/llvm-project/lldb/source/Symbol/DWARFCallFrameInfo.cpp
+++ b/contrib/llvm-project/lldb/source/Symbol/DWARFCallFrameInfo.cpp
@@ -419,8 +419,7 @@ void DWARFCallFrameInfo::GetFDEIndex() {
if (m_fde_index_initialized) // if two threads hit the locker
return;
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%s - %s", LLVM_PRETTY_FUNCTION,
+ LLDB_SCOPED_TIMERF("%s - %s", LLVM_PRETTY_FUNCTION,
m_objfile.GetFileSpec().GetFilename().AsCString(""));
bool clear_address_zeroth_bit = false;
diff --git a/contrib/llvm-project/lldb/source/Symbol/FuncUnwinders.cpp b/contrib/llvm-project/lldb/source/Symbol/FuncUnwinders.cpp
index 30266120d05e..9a2671a08e86 100644
--- a/contrib/llvm-project/lldb/source/Symbol/FuncUnwinders.cpp
+++ b/contrib/llvm-project/lldb/source/Symbol/FuncUnwinders.cpp
@@ -183,11 +183,11 @@ class RegisterContextToInfo: public SymbolFile::RegisterInfoResolver {
public:
RegisterContextToInfo(RegisterContext &ctx) : m_ctx(ctx) {}
- const RegisterInfo *ResolveName(llvm::StringRef name) const {
+ const RegisterInfo *ResolveName(llvm::StringRef name) const override {
return m_ctx.GetRegisterInfoByName(name);
}
const RegisterInfo *ResolveNumber(lldb::RegisterKind kind,
- uint32_t number) const {
+ uint32_t number) const override {
return m_ctx.GetRegisterInfo(kind, number);
}
diff --git a/contrib/llvm-project/lldb/source/Symbol/LineTable.cpp b/contrib/llvm-project/lldb/source/Symbol/LineTable.cpp
index 19c39bd0aeb5..1d4a405ad47d 100644
--- a/contrib/llvm-project/lldb/source/Symbol/LineTable.cpp
+++ b/contrib/llvm-project/lldb/source/Symbol/LineTable.cpp
@@ -315,7 +315,7 @@ uint32_t LineTable::FindLineEntryIndexByFileIndex(
if (m_entries[idx].is_terminal_entry)
continue;
- if (llvm::find(file_indexes, m_entries[idx].file_idx) == file_indexes.end())
+ if (!llvm::is_contained(file_indexes, m_entries[idx].file_idx))
continue;
// Exact match always wins. Otherwise try to find the closest line > the
diff --git a/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFile.cpp b/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFile.cpp
index 95ae2ca7917a..ba79bf661cd3 100644
--- a/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFile.cpp
+++ b/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFile.cpp
@@ -16,6 +16,7 @@
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
#include "lldb/Utility/UUID.h"
@@ -208,9 +209,7 @@ static FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) {
const ArchSpec *arch = module_spec.GetArchitecturePtr();
const UUID *uuid = module_spec.GetUUIDPtr();
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat,
+ LLDB_SCOPED_TIMERF(
"LocateExecutableSymbolFileDsym (file = %s, arch = %s, uuid = %p)",
exec_fspec ? exec_fspec->GetFilename().AsCString("<NULL>") : "<NULL>",
arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid);
@@ -225,6 +224,7 @@ static FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) {
} else {
dsym_module_spec.GetSymbolFileSpec() = symbol_fspec;
}
+
return dsym_module_spec.GetSymbolFileSpec();
}
@@ -233,9 +233,8 @@ ModuleSpec Symbols::LocateExecutableObjectFile(const ModuleSpec &module_spec) {
const FileSpec &exec_fspec = module_spec.GetFileSpec();
const ArchSpec *arch = module_spec.GetArchitecturePtr();
const UUID *uuid = module_spec.GetUUIDPtr();
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat, "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)",
+ LLDB_SCOPED_TIMERF(
+ "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)",
exec_fspec ? exec_fspec.GetFilename().AsCString("<NULL>") : "<NULL>",
arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid);
@@ -248,6 +247,7 @@ ModuleSpec Symbols::LocateExecutableObjectFile(const ModuleSpec &module_spec) {
} else {
LocateMacOSXFilesUsingDebugSymbols(module_spec, result);
}
+
return result;
}
diff --git a/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp b/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp
index 251605085c58..2655e4de9063 100644
--- a/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp
+++ b/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp
@@ -27,6 +27,7 @@
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/ReproducerProvider.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
#include "lldb/Utility/UUID.h"
@@ -53,6 +54,17 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
return_module_spec.GetFileSpec().Clear();
return_module_spec.GetSymbolFileSpec().Clear();
+ const UUID *uuid = module_spec.GetUUIDPtr();
+ const ArchSpec *arch = module_spec.GetArchitecturePtr();
+
+ if (repro::Loader *l = repro::Reproducer::Instance().GetLoader()) {
+ static repro::SymbolFileLoader symbol_file_loader(l);
+ std::pair<FileSpec, FileSpec> paths = symbol_file_loader.GetPaths(uuid);
+ return_module_spec.GetFileSpec() = paths.first;
+ return_module_spec.GetSymbolFileSpec() = paths.second;
+ return 1;
+ }
+
int items_found = 0;
if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr ||
@@ -69,9 +81,6 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
return items_found;
}
- const UUID *uuid = module_spec.GetUUIDPtr();
- const ArchSpec *arch = module_spec.GetArchitecturePtr();
-
if (uuid && uuid->IsValid()) {
// Try and locate the dSYM file using DebugSymbols first
llvm::ArrayRef<uint8_t> module_uuid = uuid->GetBytes();
@@ -247,6 +256,12 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
}
}
+ if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
+ g->GetOrCreate<repro::SymbolFileProvider>().AddSymbolFile(
+ uuid, return_module_spec.GetFileSpec(),
+ return_module_spec.GetSymbolFileSpec());
+ }
+
return items_found;
}
@@ -327,13 +342,6 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
}
}
- cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
- CFSTR("DBGArchitecture"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- if (CFCString::FileSystemRepresentation(cf_str, str))
- module_spec.GetArchitecture().SetTriple(str.c_str());
- }
-
std::string DBGBuildSourcePath;
std::string DBGSourcePath;
@@ -464,6 +472,25 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
const UUID *uuid_ptr = module_spec.GetUUIDPtr();
const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr();
+ if (repro::Loader *l = repro::Reproducer::Instance().GetLoader()) {
+ static repro::SymbolFileLoader symbol_file_loader(l);
+ std::pair<FileSpec, FileSpec> paths = symbol_file_loader.GetPaths(uuid_ptr);
+ if (paths.first)
+ module_spec.GetFileSpec() = paths.first;
+ if (paths.second)
+ module_spec.GetSymbolFileSpec() = paths.second;
+ return true;
+ }
+
+ // Lambda to capture the state of module_spec before returning from this
+ // function.
+ auto RecordResult = [&]() {
+ if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
+ g->GetOrCreate<repro::SymbolFileProvider>().AddSymbolFile(
+ uuid_ptr, module_spec.GetFileSpec(), module_spec.GetSymbolFileSpec());
+ }
+ };
+
// It's expensive to check for the DBGShellCommands defaults setting, only do
// it once per lldb run and cache the result.
static bool g_have_checked_for_dbgshell_command = false;
@@ -489,6 +516,7 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
// When g_dbgshell_command is NULL, the user has not enabled the use of an
// external program to find the symbols, don't run it for them.
if (!force_lookup && g_dbgshell_command == NULL) {
+ RecordResult();
return false;
}
@@ -586,7 +614,7 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
&signo, // Signal int *
&command_output, // Command output
std::chrono::seconds(
- 120), // Large timeout to allow for long dsym download times
+ 640), // Large timeout to allow for long dsym download times
false); // Don't run in a shell (we don't need shell expansion)
if (error.Success() && exit_status == 0 && !command_output.empty()) {
CFCData data(CFDataCreateWithBytesNoCopy(
@@ -613,8 +641,10 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
::CFDictionaryGetKeysAndValues(plist.get(), NULL,
(const void **)&values[0]);
if (num_values == 1) {
- return GetModuleSpecInfoFromUUIDDictionary(values[0],
- module_spec);
+ success = GetModuleSpecInfoFromUUIDDictionary(values[0],
+ module_spec);
+ RecordResult();
+ return success;
} else {
for (CFIndex i = 0; i < num_values; ++i) {
ModuleSpec curr_module_spec;
@@ -623,6 +653,7 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
if (module_spec.GetArchitecture().IsCompatibleMatch(
curr_module_spec.GetArchitecture())) {
module_spec = curr_module_spec;
+ RecordResult();
return true;
}
}
@@ -644,5 +675,6 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
}
}
}
+ RecordResult();
return success;
}
diff --git a/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp b/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp
index 6b552dd0c19e..f5dcbc5467f7 100644
--- a/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp
+++ b/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp
@@ -28,143 +28,121 @@ using namespace lldb_private;
char ObjectFile::ID;
+static ObjectFileSP
+CreateObjectFromContainer(const lldb::ModuleSP &module_sp, const FileSpec *file,
+ lldb::offset_t file_offset, lldb::offset_t file_size,
+ DataBufferSP &data_sp, lldb::offset_t &data_offset) {
+ ObjectContainerCreateInstance callback;
+ for (uint32_t idx = 0;
+ (callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(
+ idx)) != nullptr;
+ ++idx) {
+ std::unique_ptr<ObjectContainer> object_container_up(callback(
+ module_sp, data_sp, data_offset, file, file_offset, file_size));
+ if (object_container_up)
+ return object_container_up->GetObjectFile(file);
+ }
+ return {};
+}
+
ObjectFileSP
ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
lldb::offset_t file_offset, lldb::offset_t file_size,
DataBufferSP &data_sp, lldb::offset_t &data_offset) {
- ObjectFileSP object_file_sp;
-
- if (module_sp) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat,
- "ObjectFile::FindPlugin (module = %s, file = %p, file_offset = "
- "0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
- module_sp->GetFileSpec().GetPath().c_str(),
- static_cast<const void *>(file), static_cast<uint64_t>(file_offset),
- static_cast<uint64_t>(file_size));
- if (file) {
- FileSpec archive_file;
- ObjectContainerCreateInstance create_object_container_callback;
-
- if (!data_sp) {
- const bool file_exists = FileSystem::Instance().Exists(*file);
- // We have an object name which most likely means we have a .o file in
- // a static archive (.a file). Try and see if we have a cached archive
- // first without reading any data first
- if (file_exists && module_sp->GetObjectName()) {
- for (uint32_t idx = 0;
- (create_object_container_callback =
- PluginManager::GetObjectContainerCreateCallbackAtIndex(
- idx)) != nullptr;
- ++idx) {
- std::unique_ptr<ObjectContainer> object_container_up(
- create_object_container_callback(module_sp, data_sp,
- data_offset, file, file_offset,
- file_size));
-
- if (object_container_up)
- object_file_sp = object_container_up->GetObjectFile(file);
-
- if (object_file_sp.get())
- return object_file_sp;
- }
- }
- // Ok, we didn't find any containers that have a named object, now lets
- // read the first 512 bytes from the file so the object file and object
- // container plug-ins can use these bytes to see if they can parse this
- // file.
- if (file_size > 0) {
- data_sp = FileSystem::Instance().CreateDataBuffer(file->GetPath(),
- 512, file_offset);
- data_offset = 0;
- }
- }
+ LLDB_SCOPED_TIMERF(
+ "ObjectFile::FindPlugin (module = %s, file = %p, file_offset = "
+ "0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
+ module_sp->GetFileSpec().GetPath().c_str(),
+ static_cast<const void *>(file), static_cast<uint64_t>(file_offset),
+ static_cast<uint64_t>(file_size));
+
+ if (!module_sp)
+ return {};
+
+ if (!file)
+ return {};
+
+ if (!data_sp) {
+ const bool file_exists = FileSystem::Instance().Exists(*file);
+ // We have an object name which most likely means we have a .o file in
+ // a static archive (.a file). Try and see if we have a cached archive
+ // first without reading any data first
+ if (file_exists && module_sp->GetObjectName()) {
+ ObjectFileSP object_file_sp = CreateObjectFromContainer(
+ module_sp, file, file_offset, file_size, data_sp, data_offset);
+ if (object_file_sp)
+ return object_file_sp;
+ }
+ // Ok, we didn't find any containers that have a named object, now lets
+ // read the first 512 bytes from the file so the object file and object
+ // container plug-ins can use these bytes to see if they can parse this
+ // file.
+ if (file_size > 0) {
+ data_sp = FileSystem::Instance().CreateDataBuffer(file->GetPath(), 512,
+ file_offset);
+ data_offset = 0;
+ }
+ }
- if (!data_sp || data_sp->GetByteSize() == 0) {
- // Check for archive file with format "/path/to/archive.a(object.o)"
- llvm::SmallString<256> path_with_object;
- module_sp->GetFileSpec().GetPath(path_with_object);
-
- ConstString archive_object;
- const bool must_exist = true;
- if (ObjectFile::SplitArchivePathWithObject(
- path_with_object, archive_file, archive_object, must_exist)) {
- file_size = FileSystem::Instance().GetByteSize(archive_file);
- if (file_size > 0) {
- file = &archive_file;
- module_sp->SetFileSpecAndObjectName(archive_file, archive_object);
- // Check if this is a object container by iterating through all
- // object container plugin instances and then trying to get an
- // object file from the container plugins since we had a name.
- // Also, don't read
- // ANY data in case there is data cached in the container plug-ins
- // (like BSD archives caching the contained objects within an
- // file).
- for (uint32_t idx = 0;
- (create_object_container_callback =
- PluginManager::GetObjectContainerCreateCallbackAtIndex(
- idx)) != nullptr;
- ++idx) {
- std::unique_ptr<ObjectContainer> object_container_up(
- create_object_container_callback(module_sp, data_sp,
- data_offset, file,
- file_offset, file_size));
-
- if (object_container_up)
- object_file_sp = object_container_up->GetObjectFile(file);
-
- if (object_file_sp.get())
- return object_file_sp;
- }
- // We failed to find any cached object files in the container plug-
- // ins, so lets read the first 512 bytes and try again below...
- data_sp = FileSystem::Instance().CreateDataBuffer(
- archive_file.GetPath(), 512, file_offset);
- }
- }
+ if (!data_sp || data_sp->GetByteSize() == 0) {
+ // Check for archive file with format "/path/to/archive.a(object.o)"
+ llvm::SmallString<256> path_with_object;
+ module_sp->GetFileSpec().GetPath(path_with_object);
+
+ FileSpec archive_file;
+ ConstString archive_object;
+ const bool must_exist = true;
+ if (ObjectFile::SplitArchivePathWithObject(path_with_object, archive_file,
+ archive_object, must_exist)) {
+ file_size = FileSystem::Instance().GetByteSize(archive_file);
+ if (file_size > 0) {
+ file = &archive_file;
+ module_sp->SetFileSpecAndObjectName(archive_file, archive_object);
+ // Check if this is a object container by iterating through all
+ // object container plugin instances and then trying to get an
+ // object file from the container plugins since we had a name.
+ // Also, don't read
+ // ANY data in case there is data cached in the container plug-ins
+ // (like BSD archives caching the contained objects within an
+ // file).
+ ObjectFileSP object_file_sp = CreateObjectFromContainer(
+ module_sp, file, file_offset, file_size, data_sp, data_offset);
+ if (object_file_sp)
+ return object_file_sp;
+ // We failed to find any cached object files in the container plug-
+ // ins, so lets read the first 512 bytes and try again below...
+ data_sp = FileSystem::Instance().CreateDataBuffer(
+ archive_file.GetPath(), 512, file_offset);
}
+ }
+ }
- if (data_sp && data_sp->GetByteSize() > 0) {
- // Check if this is a normal object file by iterating through all
- // object file plugin instances.
- ObjectFileCreateInstance create_object_file_callback;
- for (uint32_t idx = 0;
- (create_object_file_callback =
- PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) !=
- nullptr;
- ++idx) {
- object_file_sp.reset(create_object_file_callback(
- module_sp, data_sp, data_offset, file, file_offset, file_size));
- if (object_file_sp.get())
- return object_file_sp;
- }
-
- // Check if this is a object container by iterating through all object
- // container plugin instances and then trying to get an object file
- // from the container.
- for (uint32_t idx = 0;
- (create_object_container_callback =
- PluginManager::GetObjectContainerCreateCallbackAtIndex(
- idx)) != nullptr;
- ++idx) {
- std::unique_ptr<ObjectContainer> object_container_up(
- create_object_container_callback(module_sp, data_sp, data_offset,
- file, file_offset, file_size));
-
- if (object_container_up)
- object_file_sp = object_container_up->GetObjectFile(file);
-
- if (object_file_sp.get())
- return object_file_sp;
- }
- }
+ if (data_sp && data_sp->GetByteSize() > 0) {
+ // Check if this is a normal object file by iterating through all
+ // object file plugin instances.
+ ObjectFileCreateInstance callback;
+ for (uint32_t idx = 0;
+ (callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) !=
+ nullptr;
+ ++idx) {
+ ObjectFileSP object_file_sp(callback(module_sp, data_sp, data_offset,
+ file, file_offset, file_size));
+ if (object_file_sp.get())
+ return object_file_sp;
}
+
+ // Check if this is a object container by iterating through all object
+ // container plugin instances and then trying to get an object file
+ // from the container.
+ ObjectFileSP object_file_sp = CreateObjectFromContainer(
+ module_sp, file, file_offset, file_size, data_sp, data_offset);
+ if (object_file_sp)
+ return object_file_sp;
}
+
// We didn't find it, so clear our shared pointer in case it contains
// anything and return an empty shared pointer
- object_file_sp.reset();
- return object_file_sp;
+ return {};
}
ObjectFileSP ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp,
@@ -174,9 +152,7 @@ ObjectFileSP ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp,
ObjectFileSP object_file_sp;
if (module_sp) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat,
- "ObjectFile::FindPlugin (module = "
+ LLDB_SCOPED_TIMERF("ObjectFile::FindPlugin (module = "
"%s, process = %p, header_addr = "
"0x%" PRIx64 ")",
module_sp->GetFileSpec().GetPath().c_str(),
@@ -503,6 +479,9 @@ size_t ObjectFile::ReadSectionData(Section *section,
return section->GetObjectFile()->ReadSectionData(section, section_offset,
dst, dst_len);
+ if (!section->IsRelocated())
+ RelocateSection(section);
+
if (IsInMemory()) {
ProcessSP process_sp(m_process_wp.lock());
if (process_sp) {
@@ -514,9 +493,6 @@ size_t ObjectFile::ReadSectionData(Section *section,
dst_len, error);
}
} else {
- if (!section->IsRelocated())
- RelocateSection(section);
-
const lldb::offset_t section_file_size = section->GetFileSize();
if (section_offset < section_file_size) {
const size_t section_bytes_left = section_file_size - section_offset;
@@ -547,6 +523,9 @@ size_t ObjectFile::ReadSectionData(Section *section,
if (section->GetObjectFile() != this)
return section->GetObjectFile()->ReadSectionData(section, section_data);
+ if (!section->IsRelocated())
+ RelocateSection(section);
+
if (IsInMemory()) {
ProcessSP process_sp(m_process_wp.lock());
if (process_sp) {
@@ -563,17 +542,12 @@ size_t ObjectFile::ReadSectionData(Section *section,
}
}
}
- return GetData(section->GetFileOffset(), section->GetFileSize(),
- section_data);
- } else {
- // The object file now contains a full mmap'ed copy of the object file
- // data, so just use this
- if (!section->IsRelocated())
- RelocateSection(section);
-
- return GetData(section->GetFileOffset(), section->GetFileSize(),
- section_data);
}
+
+ // The object file now contains a full mmap'ed copy of the object file
+ // data, so just use this
+ return GetData(section->GetFileOffset(), section->GetFileSize(),
+ section_data);
}
bool ObjectFile::SplitArchivePathWithObject(llvm::StringRef path_with_object,
diff --git a/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp b/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp
index 12c2077154b9..8cfea35180fa 100644
--- a/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp
+++ b/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp
@@ -71,7 +71,8 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope,
const Address &addr, bool show_fullpaths,
bool show_module, bool show_inlined_frames,
bool show_function_arguments,
- bool show_function_name) const {
+ bool show_function_name,
+ bool show_inline_callsite_line_info) const {
bool dumped_something = false;
if (show_module && module_sp) {
if (show_fullpaths)
@@ -127,11 +128,17 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope,
s->Printf(" + %" PRIu64, inlined_function_offset);
}
}
- const Declaration &call_site = inlined_block_info->GetCallSite();
- if (call_site.IsValid()) {
+ if (show_inline_callsite_line_info) {
+ const Declaration &call_site = inlined_block_info->GetCallSite();
+ if (call_site.IsValid()) {
+ s->PutCString(" at ");
+ call_site.DumpStopContext(s, show_fullpaths);
+ }
+ } else if (line_entry.IsValid()) {
s->PutCString(" at ");
- call_site.DumpStopContext(s, show_fullpaths);
+ line_entry.DumpStopContext(s, show_fullpaths);
}
+
if (show_inlined_frames) {
s->EOL();
s->Indent();
@@ -204,7 +211,7 @@ void SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level,
Type *func_type = function->GetType();
if (func_type) {
s->Indent(" FuncType: ");
- func_type->GetDescription(s, level, false);
+ func_type->GetDescription(s, level, false, target);
s->EOL();
}
}
@@ -1010,11 +1017,15 @@ void SymbolContextSpecifier::Clear() {
m_type = eNothingSpecified;
}
-bool SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) {
+bool SymbolContextSpecifier::SymbolContextMatches(const SymbolContext &sc) {
if (m_type == eNothingSpecified)
return true;
- if (m_target_sp.get() != sc.target_sp.get())
+ // Only compare targets if this specifier has one and it's not the Dummy
+ // target. Otherwise if a specifier gets made in the dummy target and
+ // copied over we'll artificially fail the comparision.
+ if (m_target_sp && !m_target_sp->IsDummyTarget() &&
+ m_target_sp != sc.target_sp)
return false;
if (m_type & eModuleSpecified) {
diff --git a/contrib/llvm-project/lldb/source/Symbol/SymbolVendor.cpp b/contrib/llvm-project/lldb/source/Symbol/SymbolVendor.cpp
index 0a5acbc48eb4..0ef332a5813f 100644
--- a/contrib/llvm-project/lldb/source/Symbol/SymbolVendor.cpp
+++ b/contrib/llvm-project/lldb/source/Symbol/SymbolVendor.cpp
@@ -60,9 +60,6 @@ SymbolVendor *SymbolVendor::FindPlugin(const lldb::ModuleSP &module_sp,
SymbolVendor::SymbolVendor(const lldb::ModuleSP &module_sp)
: ModuleChild(module_sp), m_sym_file_up() {}
-// Destructor
-SymbolVendor::~SymbolVendor() {}
-
// Add a representation given an object file.
void SymbolVendor::AddSymbolFileRepresentation(const ObjectFileSP &objfile_sp) {
ModuleSP module_sp(GetModule());
diff --git a/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp b/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp
index 3f697e6076b3..7f8424334708 100644
--- a/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp
+++ b/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp
@@ -251,8 +251,7 @@ void Symtab::InitNameIndexes() {
// Protected function, no need to lock mutex...
if (!m_name_indexes_computed) {
m_name_indexes_computed = true;
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%s", LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
// Create the name index vector to be able to quickly search by name
const size_t num_symbols = m_symbols.size();
m_name_to_index.Reserve(num_symbols);
@@ -411,9 +410,8 @@ void Symtab::PreloadSymbols() {
void Symtab::AppendSymbolNamesToMap(const IndexCollection &indexes,
bool add_demangled, bool add_mangled,
NameToIndexMap &name_to_index_map) const {
+ LLDB_SCOPED_TIMER();
if (add_demangled || add_mangled) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%s", LLVM_PRETTY_FUNCTION);
std::lock_guard<std::recursive_mutex> guard(m_mutex);
// Create the name index vector to be able to quickly search by name
@@ -566,9 +564,7 @@ struct SymbolIndexComparator {
void Symtab::SortSymbolIndexesByValue(std::vector<uint32_t> &indexes,
bool remove_duplicates) const {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
// No need to sort if we have zero or one items...
if (indexes.size() <= 1)
return;
@@ -594,8 +590,7 @@ uint32_t Symtab::AppendSymbolIndexesWithName(ConstString symbol_name,
std::vector<uint32_t> &indexes) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%s", LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
if (symbol_name) {
if (!m_name_indexes_computed)
InitNameIndexes();
@@ -611,8 +606,7 @@ uint32_t Symtab::AppendSymbolIndexesWithName(ConstString symbol_name,
std::vector<uint32_t> &indexes) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%s", LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
if (symbol_name) {
const size_t old_size = indexes.size();
if (!m_name_indexes_computed)
@@ -741,8 +735,7 @@ Symtab::FindAllSymbolsWithNameAndType(ConstString name,
std::vector<uint32_t> &symbol_indexes) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%s", LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
// Initialize all of the lookup by name indexes before converting NAME to a
// uniqued string NAME_STR below.
if (!m_name_indexes_computed)
@@ -760,8 +753,7 @@ void Symtab::FindAllSymbolsWithNameAndType(
Visibility symbol_visibility, std::vector<uint32_t> &symbol_indexes) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%s", LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
// Initialize all of the lookup by name indexes before converting NAME to a
// uniqued string NAME_STR below.
if (!m_name_indexes_computed)
@@ -790,9 +782,7 @@ Symbol *Symtab::FindFirstSymbolWithNameAndType(ConstString name,
Debug symbol_debug_type,
Visibility symbol_visibility) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%s", LLVM_PRETTY_FUNCTION);
+ LLDB_SCOPED_TIMER();
if (!m_name_indexes_computed)
InitNameIndexes();
diff --git a/contrib/llvm-project/lldb/source/Symbol/Type.cpp b/contrib/llvm-project/lldb/source/Symbol/Type.cpp
index 307e99ac84b6..df5dab19dbf3 100644
--- a/contrib/llvm-project/lldb/source/Symbol/Type.cpp
+++ b/contrib/llvm-project/lldb/source/Symbol/Type.cpp
@@ -170,7 +170,7 @@ Type::Type()
}
void Type::GetDescription(Stream *s, lldb::DescriptionLevel level,
- bool show_name) {
+ bool show_name, ExecutionContextScope *exe_scope) {
*s << "id = " << (const UserID &)*this;
// Call the name accessor to make sure we resolve the type name
@@ -186,7 +186,7 @@ void Type::GetDescription(Stream *s, lldb::DescriptionLevel level,
}
// Call the get byte size accesor so we resolve our byte size
- if (GetByteSize())
+ if (GetByteSize(exe_scope))
s->Printf(", byte-size = %" PRIu64, m_byte_size);
bool show_fullpaths = (level == lldb::eDescriptionLevelVerbose);
m_decl.Dump(s, show_fullpaths);
@@ -323,7 +323,9 @@ void Type::DumpValue(ExecutionContext *exe_ctx, Stream *s,
GetForwardCompilerType().DumpValue(
exe_ctx, s, format == lldb::eFormatDefault ? GetFormat() : format, data,
- data_byte_offset, GetByteSize().getValueOr(0),
+ data_byte_offset,
+ GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr)
+ .getValueOr(0),
0, // Bitfield bit size
0, // Bitfield bit offset
show_types, show_summary, verbose, 0);
@@ -336,7 +338,7 @@ Type *Type::GetEncodingType() {
return m_encoding_type;
}
-llvm::Optional<uint64_t> Type::GetByteSize() {
+llvm::Optional<uint64_t> Type::GetByteSize(ExecutionContextScope *exe_scope) {
if (m_byte_size_has_value)
return m_byte_size;
@@ -352,14 +354,14 @@ llvm::Optional<uint64_t> Type::GetByteSize() {
case eEncodingIsTypedefUID: {
Type *encoding_type = GetEncodingType();
if (encoding_type)
- if (llvm::Optional<uint64_t> size = encoding_type->GetByteSize()) {
+ if (llvm::Optional<uint64_t> size = encoding_type->GetByteSize(exe_scope)) {
m_byte_size = *size;
m_byte_size_has_value = true;
return m_byte_size;
}
if (llvm::Optional<uint64_t> size =
- GetLayoutCompilerType().GetByteSize(nullptr)) {
+ GetLayoutCompilerType().GetByteSize(exe_scope)) {
m_byte_size = *size;
m_byte_size_has_value = true;
return m_byte_size;
@@ -373,6 +375,7 @@ llvm::Optional<uint64_t> Type::GetByteSize() {
if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture()) {
m_byte_size = arch.GetAddressByteSize();
m_byte_size_has_value = true;
+ return m_byte_size;
}
} break;
}
@@ -430,7 +433,9 @@ bool Type::ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t addr,
return false;
}
- const uint64_t byte_size = GetByteSize().getValueOr(0);
+ const uint64_t byte_size =
+ GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr)
+ .getValueOr(0);
if (data.GetByteSize() < byte_size) {
lldb::DataBufferSP data_sp(new DataBufferHeap(byte_size, '\0'));
data.SetData(data_sp);
@@ -722,6 +727,14 @@ ModuleSP Type::GetModule() {
return ModuleSP();
}
+ModuleSP Type::GetExeModule() {
+ if (m_compiler_type) {
+ SymbolFile *symbol_file = m_compiler_type.GetTypeSystem()->GetSymbolFile();
+ return symbol_file->GetObjectFile()->GetModule();
+ }
+ return ModuleSP();
+}
+
TypeAndOrName::TypeAndOrName(TypeSP &in_type_sp) {
if (in_type_sp) {
m_compiler_type = in_type_sp->GetForwardCompilerType();
@@ -816,6 +829,7 @@ TypeImpl::TypeImpl(const CompilerType &static_type,
void TypeImpl::SetType(const lldb::TypeSP &type_sp) {
if (type_sp) {
m_static_type = type_sp->GetForwardCompilerType();
+ m_exe_module_wp = type_sp->GetExeModule();
m_module_wp = type_sp->GetModule();
} else {
m_static_type.Clear();
@@ -842,6 +856,15 @@ void TypeImpl::SetType(const CompilerType &compiler_type,
}
bool TypeImpl::CheckModule(lldb::ModuleSP &module_sp) const {
+ return CheckModuleCommon(m_module_wp, module_sp);
+}
+
+bool TypeImpl::CheckExeModule(lldb::ModuleSP &module_sp) const {
+ return CheckModuleCommon(m_exe_module_wp, module_sp);
+}
+
+bool TypeImpl::CheckModuleCommon(const lldb::ModuleWP &input_module_wp,
+ lldb::ModuleSP &module_sp) const {
// Check if we have a module for this type. If we do and the shared pointer
// is can be successfully initialized with m_module_wp, return true. Else
// return false if we didn't have a module, or if we had a module and it has
@@ -850,7 +873,7 @@ bool TypeImpl::CheckModule(lldb::ModuleSP &module_sp) const {
// this function returns true. If we have a module, the "module_sp" will be
// filled in with a strong reference to the module so that the module will at
// least stay around long enough for the type query to succeed.
- module_sp = m_module_wp.lock();
+ module_sp = input_module_wp.lock();
if (!module_sp) {
lldb::ModuleWP empty_module_wp;
// If either call to "std::weak_ptr::owner_before(...) value returns true,
@@ -858,9 +881,9 @@ bool TypeImpl::CheckModule(lldb::ModuleSP &module_sp) const {
// reference to a valid shared pointer. This helps us know if we had a
// valid reference to a section which is now invalid because the module it
// was in was deleted
- if (empty_module_wp.owner_before(m_module_wp) ||
- m_module_wp.owner_before(empty_module_wp)) {
- // m_module_wp had a valid reference to a module, but all strong
+ if (empty_module_wp.owner_before(input_module_wp) ||
+ input_module_wp.owner_before(empty_module_wp)) {
+ // input_module_wp had a valid reference to a module, but all strong
// references have been released and the module has been deleted
return false;
}
@@ -894,6 +917,13 @@ void TypeImpl::Clear() {
m_dynamic_type.Clear();
}
+ModuleSP TypeImpl::GetModule() const {
+ lldb::ModuleSP module_sp;
+ if (CheckExeModule(module_sp))
+ return module_sp;
+ return nullptr;
+}
+
ConstString TypeImpl::GetName() const {
ModuleSP module_sp;
if (CheckModule(module_sp)) {
diff --git a/contrib/llvm-project/lldb/source/Symbol/TypeSystem.cpp b/contrib/llvm-project/lldb/source/Symbol/TypeSystem.cpp
index 5e57813c28bd..2adf36fa8276 100644
--- a/contrib/llvm-project/lldb/source/Symbol/TypeSystem.cpp
+++ b/contrib/llvm-project/lldb/source/Symbol/TypeSystem.cpp
@@ -6,22 +6,14 @@
//
//===----------------------------------------------------------------------===//
-//
-// TypeSystem.cpp
-// lldb
-//
-// Created by Ryan Brown on 3/29/15.
-//
-//
-
#include "lldb/Symbol/TypeSystem.h"
-
-#include <set>
-
#include "lldb/Core/PluginManager.h"
+#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Language.h"
+#include <set>
+
using namespace lldb_private;
using namespace lldb;
@@ -179,6 +171,11 @@ TypeSystem::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name,
return std::vector<CompilerDecl>();
}
+std::unique_ptr<UtilityFunction>
+TypeSystem::CreateUtilityFunction(std::string text, std::string name) {
+ return {};
+}
+
#pragma mark TypeSystemMap
TypeSystemMap::TypeSystemMap()
@@ -224,9 +221,9 @@ void TypeSystemMap::ForEach(std::function<bool(TypeSystem *)> const &callback) {
}
}
-llvm::Expected<TypeSystem &>
-TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
- Module *module, bool can_create) {
+llvm::Expected<TypeSystem &> TypeSystemMap::GetTypeSystemForLanguage(
+ lldb::LanguageType language,
+ llvm::Optional<CreateCallback> create_callback) {
llvm::Error error = llvm::Error::success();
assert(!error); // Check the success value when assertions are enabled
std::lock_guard<std::mutex> guard(m_mutex);
@@ -268,7 +265,7 @@ TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
}
}
- if (!can_create) {
+ if (!create_callback) {
error = llvm::make_error<llvm::StringError>(
"Unable to find type system for language " +
llvm::StringRef(Language::GetNameForLanguageType(language)),
@@ -276,7 +273,7 @@ TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
} else {
// Cache even if we get a shared pointer that contains a null type system
// back
- auto type_system_sp = TypeSystem::CreateInstance(language, module);
+ TypeSystemSP type_system_sp = (*create_callback)();
m_map[language] = type_system_sp;
if (type_system_sp.get()) {
llvm::consumeError(std::move(error));
@@ -295,69 +292,24 @@ TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
llvm::Expected<TypeSystem &>
TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
- Target *target, bool can_create) {
- llvm::Error error = llvm::Error::success();
- assert(!error); // Check the success value when assertions are enabled
- std::lock_guard<std::mutex> guard(m_mutex);
- if (m_clear_in_progress) {
- error = llvm::make_error<llvm::StringError>(
- "Unable to get TypeSystem because TypeSystemMap is being cleared",
- llvm::inconvertibleErrorCode());
- } else {
- collection::iterator pos = m_map.find(language);
- if (pos != m_map.end()) {
- auto *type_system = pos->second.get();
- if (type_system) {
- llvm::consumeError(std::move(error));
- return *type_system;
- }
- error = llvm::make_error<llvm::StringError>(
- "TypeSystem for language " +
- llvm::StringRef(Language::GetNameForLanguageType(language)) +
- " doesn't exist",
- llvm::inconvertibleErrorCode());
- return std::move(error);
- }
-
- for (const auto &pair : m_map) {
- if (pair.second && pair.second->SupportsLanguage(language)) {
- // Add a new mapping for "language" to point to an already existing
- // TypeSystem that supports this language
- m_map[language] = pair.second;
- if (pair.second.get()) {
- llvm::consumeError(std::move(error));
- return *pair.second.get();
- }
- error = llvm::make_error<llvm::StringError>(
- "TypeSystem for language " +
- llvm::StringRef(Language::GetNameForLanguageType(language)) +
- " doesn't exist",
- llvm::inconvertibleErrorCode());
- return std::move(error);
- }
- }
-
- if (!can_create) {
- error = llvm::make_error<llvm::StringError>(
- "Unable to find type system for language " +
- llvm::StringRef(Language::GetNameForLanguageType(language)),
- llvm::inconvertibleErrorCode());
- } else {
- // Cache even if we get a shared pointer that contains a null type system
- // back
- auto type_system_sp = TypeSystem::CreateInstance(language, target);
- m_map[language] = type_system_sp;
- if (type_system_sp.get()) {
- llvm::consumeError(std::move(error));
- return *type_system_sp.get();
- }
- error = llvm::make_error<llvm::StringError>(
- "TypeSystem for language " +
- llvm::StringRef(Language::GetNameForLanguageType(language)) +
- " doesn't exist",
- llvm::inconvertibleErrorCode());
- }
+ Module *module, bool can_create) {
+ if (can_create) {
+ return GetTypeSystemForLanguage(
+ language, llvm::Optional<CreateCallback>([language, module]() {
+ return TypeSystem::CreateInstance(language, module);
+ }));
}
+ return GetTypeSystemForLanguage(language);
+}
- return std::move(error);
+llvm::Expected<TypeSystem &>
+TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
+ Target *target, bool can_create) {
+ if (can_create) {
+ return GetTypeSystemForLanguage(
+ language, llvm::Optional<CreateCallback>([language, target]() {
+ return TypeSystem::CreateInstance(language, target);
+ }));
+ }
+ return GetTypeSystemForLanguage(language);
}
diff --git a/contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp b/contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp
index e8906f38e2ff..d24cabed14ce 100644
--- a/contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp
+++ b/contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp
@@ -83,7 +83,7 @@ static void DumpDWARFExpr(Stream &s, llvm::ArrayRef<uint8_t> expr, Thread *threa
llvm::DataExtractor data(expr, order_and_width->first == eByteOrderLittle,
order_and_width->second);
llvm::DWARFExpression(data, order_and_width->second, llvm::dwarf::DWARF32)
- .print(s.AsRawOstream(), nullptr, nullptr);
+ .print(s.AsRawOstream(), llvm::DIDumpOptions(), nullptr, nullptr);
} else
s.PutCString("dwarf-expr");
}
@@ -527,6 +527,18 @@ void UnwindPlan::Dump(Stream &s, Thread *thread, lldb::addr_t base_addr) const {
s.Printf("not specified.\n");
break;
}
+ s.Printf("This UnwindPlan is for a trap handler function: ");
+ switch (m_plan_is_for_signal_trap) {
+ case eLazyBoolYes:
+ s.Printf("yes.\n");
+ break;
+ case eLazyBoolNo:
+ s.Printf("no.\n");
+ break;
+ case eLazyBoolCalculate:
+ s.Printf("not specified.\n");
+ break;
+ }
if (m_plan_valid_address_range.GetBaseAddress().IsValid() &&
m_plan_valid_address_range.GetByteSize() > 0) {
s.PutCString("Address range of this UnwindPlan: ");
diff --git a/contrib/llvm-project/lldb/source/Symbol/Variable.cpp b/contrib/llvm-project/lldb/source/Symbol/Variable.cpp
index 6c18ef15e1a2..62b16011fe66 100644
--- a/contrib/llvm-project/lldb/source/Symbol/Variable.cpp
+++ b/contrib/llvm-project/lldb/source/Symbol/Variable.cpp
@@ -40,12 +40,13 @@ Variable::Variable(lldb::user_id_t uid, const char *name, const char *mangled,
ValueType scope, SymbolContextScope *context,
const RangeList &scope_range, Declaration *decl_ptr,
const DWARFExpression &location, bool external,
- bool artificial, bool static_member)
+ bool artificial, bool location_is_constant_data,
+ bool static_member)
: UserID(uid), m_name(name), m_mangled(ConstString(mangled)),
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),
- m_artificial(artificial), m_loc_is_const_data(false),
+ m_artificial(artificial), m_loc_is_const_data(location_is_constant_data),
m_static_member(static_member) {}
Variable::~Variable() {}
diff --git a/contrib/llvm-project/lldb/source/Target/ABI.cpp b/contrib/llvm-project/lldb/source/Target/ABI.cpp
index 4320eb93adfc..f6a531136dcb 100644
--- a/contrib/llvm-project/lldb/source/Target/ABI.cpp
+++ b/contrib/llvm-project/lldb/source/Target/ABI.cpp
@@ -42,27 +42,22 @@ ABI::FindPlugin(lldb::ProcessSP process_sp, const ArchSpec &arch) {
ABI::~ABI() = default;
-bool RegInfoBasedABI::GetRegisterInfoByName(ConstString name, RegisterInfo &info) {
+bool RegInfoBasedABI::GetRegisterInfoByName(llvm::StringRef name,
+ RegisterInfo &info) {
uint32_t count = 0;
const RegisterInfo *register_info_array = GetRegisterInfoArray(count);
if (register_info_array) {
- const char *unique_name_cstr = name.GetCString();
uint32_t i;
for (i = 0; i < count; ++i) {
const char *reg_name = register_info_array[i].name;
- assert(ConstString(reg_name).GetCString() == reg_name &&
- "register_info_array[i].name not from a ConstString?");
- if (reg_name == unique_name_cstr) {
+ if (reg_name == name) {
info = register_info_array[i];
return true;
}
}
for (i = 0; i < count; ++i) {
const char *reg_alt_name = register_info_array[i].alt_name;
- assert((reg_alt_name == nullptr ||
- ConstString(reg_alt_name).GetCString() == reg_alt_name) &&
- "register_info_array[i].alt_name not from a ConstString?");
- if (reg_alt_name == unique_name_cstr) {
+ if (reg_alt_name == name) {
info = register_info_array[i];
return true;
}
@@ -130,7 +125,6 @@ ValueObjectSP ABI::GetReturnValueObject(Thread &thread, CompilerType &ast_type,
// we don't do anything with these for now
break;
case Value::eValueTypeScalar:
- case Value::eValueTypeVector:
expr_variable_sp->m_flags |=
ExpressionVariable::EVIsFreezeDried;
expr_variable_sp->m_flags |=
@@ -224,7 +218,7 @@ void RegInfoBasedABI::AugmentRegisterInfo(RegisterInfo &info) {
return;
RegisterInfo abi_info;
- if (!GetRegisterInfoByName(ConstString(info.name), abi_info))
+ if (!GetRegisterInfoByName(info.name, abi_info))
return;
if (info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM)
diff --git a/contrib/llvm-project/lldb/source/Target/AssertFrameRecognizer.cpp b/contrib/llvm-project/lldb/source/Target/AssertFrameRecognizer.cpp
index d87459ac2fdd..cb671040d14f 100644
--- a/contrib/llvm-project/lldb/source/Target/AssertFrameRecognizer.cpp
+++ b/contrib/llvm-project/lldb/source/Target/AssertFrameRecognizer.cpp
@@ -86,20 +86,17 @@ bool GetAssertLocation(llvm::Triple::OSType os, SymbolLocation &location) {
}
void RegisterAssertFrameRecognizer(Process *process) {
- static llvm::once_flag g_once_flag;
- llvm::call_once(g_once_flag, [process]() {
- Target &target = process->GetTarget();
- llvm::Triple::OSType os = target.GetArchitecture().GetTriple().getOS();
- SymbolLocation location;
-
- if (!GetAbortLocation(os, location))
- return;
-
- StackFrameRecognizerManager::AddRecognizer(
- StackFrameRecognizerSP(new AssertFrameRecognizer()),
- location.module_spec.GetFilename(), location.symbols,
- /*first_instruction_only*/ false);
- });
+ Target &target = process->GetTarget();
+ llvm::Triple::OSType os = target.GetArchitecture().GetTriple().getOS();
+ SymbolLocation location;
+
+ if (!GetAbortLocation(os, location))
+ return;
+
+ target.GetFrameRecognizerManager().AddRecognizer(
+ StackFrameRecognizerSP(new AssertFrameRecognizer()),
+ location.module_spec.GetFilename(), location.symbols,
+ /*first_instruction_only*/ false);
}
} // namespace lldb_private
@@ -133,7 +130,8 @@ AssertFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
SymbolContext sym_ctx =
prev_frame_sp->GetSymbolContext(eSymbolContextEverything);
- if (!sym_ctx.module_sp->GetFileSpec().FileEquals(location.module_spec))
+ if (!sym_ctx.module_sp ||
+ !sym_ctx.module_sp->GetFileSpec().FileEquals(location.module_spec))
continue;
ConstString func_name = sym_ctx.GetFunctionName();
diff --git a/contrib/llvm-project/lldb/source/Target/LanguageRuntime.cpp b/contrib/llvm-project/lldb/source/Target/LanguageRuntime.cpp
index 58ad70c2b902..f2e2febf8b88 100644
--- a/contrib/llvm-project/lldb/source/Target/LanguageRuntime.cpp
+++ b/contrib/llvm-project/lldb/source/Target/LanguageRuntime.cpp
@@ -202,26 +202,19 @@ protected:
LanguageRuntime *LanguageRuntime::FindPlugin(Process *process,
lldb::LanguageType language) {
- std::unique_ptr<LanguageRuntime> language_runtime_up;
LanguageRuntimeCreateInstance create_callback;
-
for (uint32_t idx = 0;
(create_callback =
PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) !=
nullptr;
++idx) {
- language_runtime_up.reset(create_callback(process, language));
-
- if (language_runtime_up)
- return language_runtime_up.release();
+ if (LanguageRuntime *runtime = create_callback(process, language))
+ return runtime;
}
-
return nullptr;
}
-LanguageRuntime::LanguageRuntime(Process *process) : m_process(process) {}
-
-LanguageRuntime::~LanguageRuntime() = default;
+LanguageRuntime::LanguageRuntime(Process *process) : Runtime(process) {}
BreakpointPreconditionSP
LanguageRuntime::GetExceptionPrecondition(LanguageType language,
diff --git a/contrib/llvm-project/lldb/source/Target/MemoryRegionInfo.cpp b/contrib/llvm-project/lldb/source/Target/MemoryRegionInfo.cpp
index c7fb349ee1cc..0d5ebbdbe238 100644
--- a/contrib/llvm-project/lldb/source/Target/MemoryRegionInfo.cpp
+++ b/contrib/llvm-project/lldb/source/Target/MemoryRegionInfo.cpp
@@ -13,12 +13,12 @@ using namespace lldb_private;
llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &OS,
const MemoryRegionInfo &Info) {
return OS << llvm::formatv("MemoryRegionInfo([{0}, {1}), {2:r}{3:w}{4:x}, "
- "{5}, `{6}`, {7}, {8})",
+ "{5}, `{6}`, {7}, {8}, {9})",
Info.GetRange().GetRangeBase(),
Info.GetRange().GetRangeEnd(), Info.GetReadable(),
Info.GetWritable(), Info.GetExecutable(),
Info.GetMapped(), Info.GetName(), Info.GetFlash(),
- Info.GetBlocksize());
+ Info.GetBlocksize(), Info.GetMemoryTagged());
}
void llvm::format_provider<MemoryRegionInfo::OptionalBool>::format(
diff --git a/contrib/llvm-project/lldb/source/Target/OperatingSystem.cpp b/contrib/llvm-project/lldb/source/Target/OperatingSystem.cpp
index ddffab4553cc..033a806460da 100644
--- a/contrib/llvm-project/lldb/source/Target/OperatingSystem.cpp
+++ b/contrib/llvm-project/lldb/source/Target/OperatingSystem.cpp
@@ -44,8 +44,6 @@ OperatingSystem *OperatingSystem::FindPlugin(Process *process,
OperatingSystem::OperatingSystem(Process *process) : m_process(process) {}
-OperatingSystem::~OperatingSystem() = default;
-
bool OperatingSystem::IsOperatingSystemPluginThread(
const lldb::ThreadSP &thread_sp) {
if (thread_sp)
diff --git a/contrib/llvm-project/lldb/source/Target/Platform.cpp b/contrib/llvm-project/lldb/source/Target/Platform.cpp
index e5afb4c7b8d7..a77ecddfbab6 100644
--- a/contrib/llvm-project/lldb/source/Target/Platform.cpp
+++ b/contrib/llvm-project/lldb/source/Target/Platform.cpp
@@ -85,7 +85,7 @@ PlatformProperties::PlatformProperties() {
return;
llvm::SmallString<64> user_home_dir;
- if (!llvm::sys::path::home_directory(user_home_dir))
+ if (!FileSystem::Instance().GetHomeDirectory(user_home_dir))
return;
module_cache_dir = FileSpec(user_home_dir.c_str());
@@ -1020,7 +1020,6 @@ Status Platform::LaunchProcess(ProcessLaunchInfo &launch_info) {
launch_info.GetFlags().Set(eLaunchFlagLaunchInTTY);
if (launch_info.GetFlags().Test(eLaunchFlagLaunchInShell)) {
- const bool is_localhost = true;
const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug);
const bool first_arg_is_full_shell_command = false;
uint32_t num_resumes = GetResumeCountForLaunchInfo(launch_info);
@@ -1034,8 +1033,7 @@ Status Platform::LaunchProcess(ProcessLaunchInfo &launch_info) {
}
if (!launch_info.ConvertArgumentsForLaunchingInShell(
- error, is_localhost, will_debug, first_arg_is_full_shell_command,
- num_resumes))
+ error, will_debug, first_arg_is_full_shell_command, num_resumes))
return error;
} else if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) {
error = ShellExpandArguments(launch_info);
@@ -1318,7 +1316,23 @@ MmapArgList Platform::GetMmapArgumentList(const ArchSpec &arch, addr_t addr,
}
lldb_private::Status Platform::RunShellCommand(
- const char *command, // Shouldn't be nullptr
+ llvm::StringRef command,
+ const FileSpec &
+ working_dir, // Pass empty FileSpec to use the current working directory
+ 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
+ const Timeout<std::micro> &timeout) {
+ return RunShellCommand(llvm::StringRef(), command, working_dir, status_ptr,
+ signo_ptr, command_output, timeout);
+}
+
+lldb_private::Status Platform::RunShellCommand(
+ llvm::StringRef shell, // Pass empty if you want to use the default
+ // shell interpreter
+ llvm::StringRef command, // Shouldn't be empty
const FileSpec &
working_dir, // Pass empty FileSpec to use the current working directory
int *status_ptr, // Pass nullptr if you don't want the process exit status
@@ -1328,8 +1342,8 @@ lldb_private::Status Platform::RunShellCommand(
*command_output, // Pass nullptr if you don't want the command output
const Timeout<std::micro> &timeout) {
if (IsHost())
- return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr,
- command_output, timeout);
+ return Host::RunShellCommand(shell, command, working_dir, status_ptr,
+ signo_ptr, command_output, timeout);
else
return Status("unimplemented");
}
@@ -1817,10 +1831,8 @@ lldb::ProcessSP Platform::DoConnectProcess(llvm::StringRef connect_url,
if (!target || error.Fail())
return nullptr;
- debugger.GetTargetList().SetSelectedTarget(target);
-
lldb::ProcessSP process_sp =
- target->CreateProcess(debugger.GetListener(), plugin_name, nullptr);
+ target->CreateProcess(debugger.GetListener(), plugin_name, nullptr, true);
if (!process_sp)
return nullptr;
diff --git a/contrib/llvm-project/lldb/source/Target/Process.cpp b/contrib/llvm-project/lldb/source/Target/Process.cpp
index d777a2713911..518a6934059e 100644
--- a/contrib/llvm-project/lldb/source/Target/Process.cpp
+++ b/contrib/llvm-project/lldb/source/Target/Process.cpp
@@ -278,6 +278,12 @@ std::chrono::seconds ProcessProperties::GetUtilityExpressionTimeout() const {
return std::chrono::seconds(value);
}
+bool ProcessProperties::GetSteppingRunsAllThreads() const {
+ const uint32_t idx = ePropertySteppingRunsAllThreads;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_process_properties[idx].default_uint_value != 0);
+}
+
bool ProcessProperties::GetOSPluginReportsAllThreads() const {
const bool fail_value = true;
const Property *exp_property =
@@ -301,179 +307,11 @@ void ProcessProperties::SetOSPluginReportsAllThreads(bool does_report) {
nullptr, ePropertyOSPluginReportsAllThreads, does_report);
}
-Status ProcessLaunchCommandOptions::SetOptionValue(
- uint32_t option_idx, llvm::StringRef option_arg,
- ExecutionContext *execution_context) {
- Status error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option) {
- case 's': // Stop at program entry point
- launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
- break;
-
- case 'i': // STDIN for read only
- {
- FileAction action;
- if (action.Open(STDIN_FILENO, FileSpec(option_arg), true, false))
- launch_info.AppendFileAction(action);
- break;
- }
-
- case 'o': // Open STDOUT for write only
- {
- FileAction action;
- if (action.Open(STDOUT_FILENO, FileSpec(option_arg), false, true))
- launch_info.AppendFileAction(action);
- break;
- }
-
- case 'e': // STDERR for write only
- {
- FileAction action;
- if (action.Open(STDERR_FILENO, FileSpec(option_arg), false, true))
- launch_info.AppendFileAction(action);
- break;
- }
-
- case 'p': // Process plug-in name
- launch_info.SetProcessPluginName(option_arg);
- break;
-
- case 'n': // Disable STDIO
- {
- FileAction action;
- const FileSpec dev_null(FileSystem::DEV_NULL);
- if (action.Open(STDIN_FILENO, dev_null, true, false))
- launch_info.AppendFileAction(action);
- if (action.Open(STDOUT_FILENO, dev_null, false, true))
- launch_info.AppendFileAction(action);
- if (action.Open(STDERR_FILENO, dev_null, false, true))
- launch_info.AppendFileAction(action);
- break;
- }
-
- case 'w':
- launch_info.SetWorkingDirectory(FileSpec(option_arg));
- break;
-
- case 't': // Open process in new terminal window
- launch_info.GetFlags().Set(eLaunchFlagLaunchInTTY);
- break;
-
- case 'a': {
- TargetSP target_sp =
- execution_context ? execution_context->GetTargetSP() : TargetSP();
- PlatformSP platform_sp =
- target_sp ? target_sp->GetPlatform() : PlatformSP();
- launch_info.GetArchitecture() =
- Platform::GetAugmentedArchSpec(platform_sp.get(), option_arg);
- } break;
-
- case 'A': // Disable ASLR.
- {
- bool success;
- const bool disable_aslr_arg =
- OptionArgParser::ToBoolean(option_arg, true, &success);
- if (success)
- disable_aslr = disable_aslr_arg ? eLazyBoolYes : eLazyBoolNo;
- else
- error.SetErrorStringWithFormat(
- "Invalid boolean value for disable-aslr option: '%s'",
- option_arg.empty() ? "<null>" : option_arg.str().c_str());
- break;
- }
-
- case 'X': // shell expand args.
- {
- bool success;
- const bool expand_args =
- OptionArgParser::ToBoolean(option_arg, true, &success);
- if (success)
- launch_info.SetShellExpandArguments(expand_args);
- else
- error.SetErrorStringWithFormat(
- "Invalid boolean value for shell-expand-args option: '%s'",
- option_arg.empty() ? "<null>" : option_arg.str().c_str());
- break;
- }
-
- case 'c':
- if (!option_arg.empty())
- launch_info.SetShell(FileSpec(option_arg));
- else
- launch_info.SetShell(HostInfo::GetDefaultShell());
- break;
-
- case 'v':
- launch_info.GetEnvironment().insert(option_arg);
- break;
-
- default:
- error.SetErrorStringWithFormat("unrecognized short option character '%c'",
- short_option);
- break;
- }
- return error;
-}
-
-static constexpr OptionDefinition g_process_launch_options[] = {
- {LLDB_OPT_SET_ALL, false, "stop-at-entry", 's', OptionParser::eNoArgument,
- 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, {}, 0, eArgTypeBoolean,
- "Set whether to disable address space layout randomization when launching "
- "a process."},
- {LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument,
- nullptr, {}, 0, eArgTypePlugin,
- "Name of the process plugin you want to use."},
- {LLDB_OPT_SET_ALL, false, "working-dir", 'w',
- OptionParser::eRequiredArgument, nullptr, {}, 0,
- eArgTypeDirectoryName,
- "Set the current working directory to <path> when running the inferior."},
- {LLDB_OPT_SET_ALL, false, "arch", 'a', OptionParser::eRequiredArgument,
- nullptr, {}, 0, eArgTypeArchitecture,
- "Set the architecture for the process to launch when ambiguous."},
- {LLDB_OPT_SET_ALL, false, "environment", 'v',
- OptionParser::eRequiredArgument, 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, {}, 0, eArgTypeFilename,
- "Run the process in a shell (not supported on all platforms)."},
-
- {LLDB_OPT_SET_1, false, "stdin", 'i', OptionParser::eRequiredArgument,
- nullptr, {}, 0, eArgTypeFilename,
- "Redirect stdin for the process to <filename>."},
- {LLDB_OPT_SET_1, false, "stdout", 'o', OptionParser::eRequiredArgument,
- nullptr, {}, 0, eArgTypeFilename,
- "Redirect stdout for the process to <filename>."},
- {LLDB_OPT_SET_1, false, "stderr", 'e', OptionParser::eRequiredArgument,
- nullptr, {}, 0, eArgTypeFilename,
- "Redirect stderr for the process to <filename>."},
-
- {LLDB_OPT_SET_2, false, "tty", 't', OptionParser::eNoArgument, nullptr,
- {}, 0, eArgTypeNone,
- "Start the process in a terminal (not supported on all platforms)."},
-
- {LLDB_OPT_SET_3, false, "no-stdio", 'n', OptionParser::eNoArgument, 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, {}, 0, eArgTypeBoolean,
- "Set whether to shell expand arguments to the process when launching."},
-};
-
-llvm::ArrayRef<OptionDefinition> ProcessLaunchCommandOptions::GetDefinitions() {
- return llvm::makeArrayRef(g_process_launch_options);
-}
-
ProcessSP Process::FindPlugin(lldb::TargetSP target_sp,
llvm::StringRef plugin_name,
ListenerSP listener_sp,
- const FileSpec *crash_file_path) {
+ const FileSpec *crash_file_path,
+ bool can_connect) {
static uint32_t g_process_unique_id = 0;
ProcessSP process_sp;
@@ -483,7 +321,8 @@ ProcessSP Process::FindPlugin(lldb::TargetSP target_sp,
create_callback =
PluginManager::GetProcessCreateCallbackForPluginName(const_plugin_name);
if (create_callback) {
- process_sp = create_callback(target_sp, listener_sp, crash_file_path);
+ process_sp = create_callback(target_sp, listener_sp, crash_file_path,
+ can_connect);
if (process_sp) {
if (process_sp->CanDebug(target_sp, true)) {
process_sp->m_process_unique_id = ++g_process_unique_id;
@@ -496,7 +335,8 @@ ProcessSP Process::FindPlugin(lldb::TargetSP target_sp,
(create_callback =
PluginManager::GetProcessCreateCallbackAtIndex(idx)) != nullptr;
++idx) {
- process_sp = create_callback(target_sp, listener_sp, crash_file_path);
+ process_sp = create_callback(target_sp, listener_sp, crash_file_path,
+ can_connect);
if (process_sp) {
if (process_sp->CanDebug(target_sp, false)) {
process_sp->m_process_unique_id = ++g_process_unique_id;
@@ -523,7 +363,7 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp)
Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp,
const UnixSignalsSP &unix_signals_sp)
- : ProcessProperties(this), UserID(LLDB_INVALID_PROCESS_ID),
+ : ProcessProperties(this),
Broadcaster((target_sp->GetDebugger().GetBroadcasterManager()),
Process::GetStaticBroadcasterClass().AsCString()),
m_target_wp(target_sp), m_public_state(eStateUnloaded),
@@ -547,7 +387,7 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp,
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_up(), m_public_run_lock(),
- m_private_run_lock(), m_finalizing(false), m_finalize_called(false),
+ m_private_run_lock(), m_finalizing(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(),
@@ -623,7 +463,8 @@ const ProcessPropertiesSP &Process::GetGlobalProperties() {
}
void Process::Finalize() {
- m_finalizing = true;
+ if (m_finalizing.exchange(true))
+ return;
// Destroy this process if needed
switch (GetPrivateState()) {
@@ -635,7 +476,7 @@ void Process::Finalize() {
case eStateStepping:
case eStateCrashed:
case eStateSuspended:
- Destroy(false);
+ DestroyImpl(false);
break;
case eStateInvalid:
@@ -698,7 +539,6 @@ void Process::Finalize() {
m_private_run_lock.TrySetRunning(); // This will do nothing if already locked
m_private_run_lock.SetStopped();
m_structured_data_plugin_map.clear();
- m_finalize_called = true;
}
void Process::RegisterNotificationCallbacks(const Notifications &callbacks) {
@@ -1239,6 +1079,12 @@ bool Process::SetProcessExitStatus(
return false;
}
+bool Process::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ m_thread_plans.ClearThreadCache();
+ return DoUpdateThreadList(old_thread_list, new_thread_list);
+}
+
void Process::UpdateThreadListIfNeeded() {
const uint32_t stop_id = GetStopID();
if (m_thread_list.GetSize(false) == 0 ||
@@ -1507,7 +1353,7 @@ bool Process::StateChangedIsHijackedForSynchronousResume() {
StateType Process::GetPrivateState() { return m_private_state.GetValue(); }
void Process::SetPrivateState(StateType new_state) {
- if (m_finalize_called)
+ if (m_finalizing)
return;
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE |
@@ -1557,11 +1403,7 @@ void Process::SetPrivateState(StateType new_state) {
StateAsCString(new_state), m_mod_id.GetStopID());
}
- // Use our target to get a shared pointer to ourselves...
- if (m_finalize_called && !PrivateStateThreadIsValid())
- BroadcastEvent(event_sp);
- else
- m_private_state_broadcaster.BroadcastEvent(event_sp);
+ m_private_state_broadcaster.BroadcastEvent(event_sp);
} else {
LLDB_LOGF(log,
"Process::SetPrivateState (%s) state didn't change. Ignoring...",
@@ -2291,6 +2133,9 @@ size_t Process::WriteMemory(addr_t addr, const void *buf, size_t size,
if (error.Fail())
return;
+ if (bp->GetType() != BreakpointSite::eSoftware)
+ return;
+
addr_t intersect_addr;
size_t intersect_size;
size_t opcode_offset;
@@ -3068,13 +2913,8 @@ void Process::CompleteAttach() {
}
}
// Figure out which one is the executable, and set that in our target:
- const ModuleList &target_modules = GetTarget().GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
- size_t num_modules = target_modules.GetSize();
ModuleSP new_executable_module_sp;
-
- for (size_t i = 0; i < num_modules; i++) {
- ModuleSP module_sp(target_modules.GetModuleAtIndexUnlocked(i));
+ for (ModuleSP module_sp : GetTarget().GetImages().Modules()) {
if (module_sp && module_sp->IsExecutable()) {
if (GetTarget().GetExecutableModulePointer() != module_sp.get())
new_executable_module_sp = module_sp;
@@ -3154,7 +2994,7 @@ Status Process::PrivateResume() {
if (m_thread_list.WillResume()) {
// Last thing, do the PreResumeActions.
if (!RunPreResumeActions()) {
- error.SetErrorStringWithFormat(
+ error.SetErrorString(
"Process::PrivateResume PreResumeActions failed, not resuming.");
} else {
m_mod_id.BumpResumeID();
@@ -3333,9 +3173,12 @@ Status Process::Detach(bool keep_stopped) {
Status Process::Destroy(bool force_kill) {
// If we've already called Process::Finalize then there's nothing useful to
// be done here. Finalize has actually called Destroy already.
- if (m_finalize_called)
+ if (m_finalizing)
return {};
+ return DestroyImpl(force_kill);
+}
+Status Process::DestroyImpl(bool force_kill) {
// Tell ourselves we are in the process of destroying the process, so that we
// don't do any unnecessary work that might hinder the destruction. Remember
// to set this back to false when we are done. That way if the attempt
@@ -4169,8 +4012,7 @@ void Process::ProcessEventData::DoOnRemoval(Event *event_ptr) {
// public (or SyncResume) broadcasters. StopHooks are just for
// real public stops. They might also restart the target,
// so watch for that.
- process_sp->GetTarget().RunStopHooks();
- if (process_sp->GetPrivateState() == eStateRunning)
+ if (process_sp->GetTarget().RunStopHooks())
SetRestarted(true);
}
}
@@ -5757,41 +5599,25 @@ addr_t Process::ResolveIndirectFunction(const Address *address, Status &error) {
}
void Process::ModulesDidLoad(ModuleList &module_list) {
+ // Inform the system runtime of the modified modules.
SystemRuntime *sys_runtime = GetSystemRuntime();
- if (sys_runtime) {
+ if (sys_runtime)
sys_runtime->ModulesDidLoad(module_list);
- }
GetJITLoaders().ModulesDidLoad(module_list);
- // Give runtimes a chance to be created.
+ // Give the instrumentation runtimes a chance to be created before informing
+ // them of the modified modules.
InstrumentationRuntime::ModulesDidLoad(module_list, this,
m_instrumentation_runtimes);
+ for (auto &runtime : m_instrumentation_runtimes)
+ runtime.second->ModulesDidLoad(module_list);
- // Tell runtimes about new modules.
- for (auto pos = m_instrumentation_runtimes.begin();
- pos != m_instrumentation_runtimes.end(); ++pos) {
- InstrumentationRuntimeSP runtime = pos->second;
- runtime->ModulesDidLoad(module_list);
- }
-
- // Let any language runtimes we have already created know about the modules
- // that loaded.
-
- // Iterate over a copy of this language runtime list in case the language
- // runtime ModulesDidLoad somehow causes the language runtime to be
- // unloaded.
- {
- std::lock_guard<std::recursive_mutex> guard(m_language_runtimes_mutex);
- LanguageRuntimeCollection language_runtimes(m_language_runtimes);
- for (const auto &pair : language_runtimes) {
- // We must check language_runtime_sp to make sure it is not 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);
- }
+ // Give the language runtimes a chance to be created before informing them of
+ // the modified modules.
+ for (const lldb::LanguageType lang_type : Language::GetSupportedLanguages()) {
+ if (LanguageRuntime *runtime = GetLanguageRuntime(lang_type))
+ runtime->ModulesDidLoad(module_list);
}
// If we don't have an operating system plug-in, try to load one since
@@ -5799,7 +5625,7 @@ void Process::ModulesDidLoad(ModuleList &module_list) {
if (!m_os_up)
LoadOperatingSystemPlugin(false);
- // Give structured-data plugins a chance to see the modified modules.
+ // Inform the structured-data plugins of the modified modules.
for (auto pair : m_structured_data_plugin_map) {
if (pair.second)
pair.second->ModulesDidLoad(*this, module_list);
@@ -5960,10 +5786,8 @@ Process::AdvanceAddressToNextBranchInstruction(Address default_stop_addr,
return retval;
}
- uint32_t branch_index =
- insn_list->GetIndexOfNextBranchInstruction(insn_offset, target,
- false /* ignore_calls*/,
- nullptr);
+ uint32_t branch_index = insn_list->GetIndexOfNextBranchInstruction(
+ insn_offset, false /* ignore_calls*/, nullptr);
if (branch_index == UINT32_MAX) {
return retval;
}
@@ -6138,6 +5962,13 @@ UtilityFunction *Process::GetLoadImageUtilityFunction(
return m_dlopen_utility_func_up.get();
}
+llvm::Expected<TraceTypeInfo> Process::GetSupportedTraceType() {
+ if (!IsLiveDebugSession())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Can't trace a non-live process.");
+ return llvm::make_error<UnimplementedError>();
+}
+
bool Process::CallVoidArgVoidPtrReturn(const Address *address,
addr_t &returned_func,
bool trap_exceptions) {
diff --git a/contrib/llvm-project/lldb/source/Target/ProcessTrace.cpp b/contrib/llvm-project/lldb/source/Target/ProcessTrace.cpp
new file mode 100644
index 000000000000..95f87745b724
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Target/ProcessTrace.cpp
@@ -0,0 +1,134 @@
+//===-- ProcessTrace.cpp --------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ProcessTrace.h"
+
+#include <memory>
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Target/SectionLoadList.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+ConstString ProcessTrace::GetPluginNameStatic() {
+ static ConstString g_name("trace");
+ return g_name;
+}
+
+const char *ProcessTrace::GetPluginDescriptionStatic() {
+ return "Trace process plug-in.";
+}
+
+void ProcessTrace::Terminate() {
+ PluginManager::UnregisterPlugin(ProcessTrace::CreateInstance);
+}
+
+ProcessSP ProcessTrace::CreateInstance(TargetSP target_sp,
+ ListenerSP listener_sp,
+ const FileSpec *crash_file,
+ bool can_connect) {
+ if (can_connect)
+ return nullptr;
+ return std::make_shared<ProcessTrace>(target_sp, listener_sp);
+}
+
+bool ProcessTrace::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) {
+ return plugin_specified_by_name;
+}
+
+ProcessTrace::ProcessTrace(TargetSP target_sp, ListenerSP listener_sp)
+ : PostMortemProcess(target_sp, listener_sp) {}
+
+ProcessTrace::~ProcessTrace() {
+ 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 ProcessTrace::GetPluginName() { return GetPluginNameStatic(); }
+
+uint32_t ProcessTrace::GetPluginVersion() { return 1; }
+
+void ProcessTrace::DidAttach(ArchSpec &process_arch) {
+ ListenerSP listener_sp(
+ Listener::MakeListener("lldb.process_trace.did_attach_listener"));
+ HijackProcessEvents(listener_sp);
+
+ SetCanJIT(false);
+ StartPrivateStateThread();
+ SetPrivateState(eStateStopped);
+
+ EventSP event_sp;
+ WaitForProcessToStop(llvm::None, &event_sp, true, listener_sp);
+
+ RestoreProcessEvents();
+
+ Process::DidAttach(process_arch);
+}
+
+bool ProcessTrace::DoUpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ return false;
+}
+
+void ProcessTrace::RefreshStateAfterStop() {}
+
+Status ProcessTrace::DoDestroy() { return Status(); }
+
+bool ProcessTrace::IsAlive() { return true; }
+
+size_t ProcessTrace::ReadMemory(addr_t addr, void *buf, size_t size,
+ Status &error) {
+ // Don't allow the caching that lldb_private::Process::ReadMemory does since
+ // we have it all cached in the trace files.
+ return DoReadMemory(addr, buf, size, error);
+}
+
+void ProcessTrace::Clear() { m_thread_list.Clear(); }
+
+void ProcessTrace::Initialize() {
+ static llvm::once_flag g_once_flag;
+
+ llvm::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+ });
+}
+
+ArchSpec ProcessTrace::GetArchitecture() {
+ return GetTarget().GetArchitecture();
+}
+
+bool ProcessTrace::GetProcessInfo(ProcessInstanceInfo &info) {
+ info.Clear();
+ info.SetProcessID(GetID());
+ info.SetArchitecture(GetArchitecture());
+ 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;
+}
+
+size_t ProcessTrace::DoReadMemory(addr_t addr, void *buf, size_t size,
+ Status &error) {
+ Address resolved_address;
+ GetTarget().GetSectionLoadList().ResolveLoadAddress(addr, resolved_address);
+
+ return GetTarget().ReadMemoryFromFileCache(resolved_address, buf, size,
+ error);
+}
diff --git a/contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp b/contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp
index f53158b06b8f..3a186adca04c 100644
--- a/contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp
+++ b/contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp
@@ -171,15 +171,24 @@ Status RemoteAwarePlatform::ResolveExecutable(
}
Status RemoteAwarePlatform::RunShellCommand(
- const char *command, const FileSpec &working_dir, int *status_ptr,
+ llvm::StringRef command, const FileSpec &working_dir, int *status_ptr,
int *signo_ptr, std::string *command_output,
const Timeout<std::micro> &timeout) {
+ return RunShellCommand(llvm::StringRef(), command, working_dir, status_ptr,
+ signo_ptr, command_output, timeout);
+}
+
+Status RemoteAwarePlatform::RunShellCommand(
+ llvm::StringRef shell, llvm::StringRef command, const FileSpec &working_dir,
+ int *status_ptr, int *signo_ptr, std::string *command_output,
+ const Timeout<std::micro> &timeout) {
if (IsHost())
- return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr,
- command_output, timeout);
+ return Host::RunShellCommand(shell, command, working_dir, status_ptr,
+ signo_ptr, command_output, timeout);
if (m_remote_platform_sp)
- return m_remote_platform_sp->RunShellCommand(
- command, working_dir, status_ptr, signo_ptr, command_output, timeout);
+ return m_remote_platform_sp->RunShellCommand(shell, command, working_dir,
+ status_ptr, signo_ptr,
+ command_output, timeout);
return Status("unable to run a remote command without a platform");
}
diff --git a/contrib/llvm-project/lldb/source/Target/StackFrame.cpp b/contrib/llvm-project/lldb/source/Target/StackFrame.cpp
index 3d6cc5dc90b3..131581567d73 100644
--- a/contrib/llvm-project/lldb/source/Target/StackFrame.cpp
+++ b/contrib/llvm-project/lldb/source/Target/StackFrame.cpp
@@ -229,21 +229,16 @@ bool StackFrame::ChangePC(addr_t pc) {
const char *StackFrame::Disassemble() {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (m_disassembly.Empty()) {
- ExecutionContext exe_ctx(shared_from_this());
- Target *target = exe_ctx.GetTargetPtr();
- if (target) {
- const char *plugin_name = nullptr;
- const char *flavor = nullptr;
- Disassembler::Disassemble(target->GetDebugger(),
- target->GetArchitecture(), plugin_name, flavor,
- exe_ctx, 0, false, 0, 0, m_disassembly);
- }
- if (m_disassembly.Empty())
- return nullptr;
+ if (!m_disassembly.Empty())
+ return m_disassembly.GetData();
+
+ ExecutionContext exe_ctx(shared_from_this());
+ if (Target *target = exe_ctx.GetTargetPtr()) {
+ Disassembler::Disassemble(target->GetDebugger(), target->GetArchitecture(),
+ *this, m_disassembly);
}
- return m_disassembly.GetData();
+ return m_disassembly.Empty() ? nullptr : m_disassembly.GetData();
}
Block *StackFrame::GetFrameBlock() {
@@ -1408,7 +1403,7 @@ ValueObjectSP GetValueForOffset(StackFrame &frame, ValueObjectSP &parent,
}
int64_t child_offset = child_sp->GetByteOffset();
- int64_t child_size = child_sp->GetByteSize();
+ int64_t child_size = child_sp->GetByteSize().getValueOr(0);
if (offset >= child_offset && offset < (child_offset + child_size)) {
return GetValueForOffset(frame, child_sp, offset - child_offset);
@@ -1441,8 +1436,8 @@ ValueObjectSP GetValueForDereferincingOffset(StackFrame &frame,
}
if (offset >= 0 && uint64_t(offset) >= pointee->GetByteSize()) {
- int64_t index = offset / pointee->GetByteSize();
- offset = offset % pointee->GetByteSize();
+ int64_t index = offset / pointee->GetByteSize().getValueOr(1);
+ offset = offset % pointee->GetByteSize().getValueOr(1);
const bool can_create = true;
pointee = base->GetSyntheticArrayMember(index, can_create);
}
@@ -1956,8 +1951,11 @@ bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source,
RecognizedStackFrameSP StackFrame::GetRecognizedFrame() {
if (!m_recognized_frame_sp) {
- m_recognized_frame_sp =
- StackFrameRecognizerManager::RecognizeFrame(CalculateStackFrame());
+ m_recognized_frame_sp = GetThread()
+ ->GetProcess()
+ ->GetTarget()
+ .GetFrameRecognizerManager()
+ .RecognizeFrame(CalculateStackFrame());
}
return m_recognized_frame_sp;
}
diff --git a/contrib/llvm-project/lldb/source/Target/StackFrameRecognizer.cpp b/contrib/llvm-project/lldb/source/Target/StackFrameRecognizer.cpp
index 7dc6e9d1e490..73d22d5bb4e6 100644
--- a/contrib/llvm-project/lldb/source/Target/StackFrameRecognizer.cpp
+++ b/contrib/llvm-project/lldb/source/Target/StackFrameRecognizer.cpp
@@ -6,12 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#include <vector>
+#include "lldb/Target/StackFrameRecognizer.h"
#include "lldb/Core/Module.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/StackFrame.h"
-#include "lldb/Target/StackFrameRecognizer.h"
#include "lldb/Utility/RegularExpression.h"
using namespace lldb;
@@ -48,158 +47,108 @@ ScriptedStackFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame) {
new ScriptedRecognizedStackFrame(args_synthesized));
}
-class StackFrameRecognizerManagerImpl {
-public:
- void AddRecognizer(StackFrameRecognizerSP recognizer, ConstString module,
- llvm::ArrayRef<ConstString> symbols,
- bool first_instruction_only) {
- m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer,
- false, module, RegularExpressionSP(), symbols,
- RegularExpressionSP(), first_instruction_only});
- }
-
- void AddRecognizer(StackFrameRecognizerSP recognizer,
- RegularExpressionSP module, RegularExpressionSP symbol,
- bool first_instruction_only) {
- m_recognizers.push_front(
- {(uint32_t)m_recognizers.size(), false, recognizer, true, ConstString(),
- module, std::vector<ConstString>(), symbol, first_instruction_only});
- }
-
- void ForEach(std::function<
- void(uint32_t recognized_id, std::string recognizer_name,
- std::string module, llvm::ArrayRef<ConstString> symbols,
- bool regexp)> const &callback) {
- for (auto entry : m_recognizers) {
- if (entry.is_regexp) {
- std::string module_name;
- std::string symbol_name;
-
- if (entry.module_regexp)
- module_name = entry.module_regexp->GetText().str();
- if (entry.symbol_regexp)
- symbol_name = entry.symbol_regexp->GetText().str();
-
- callback(entry.recognizer_id, entry.recognizer->GetName(), module_name,
- llvm::makeArrayRef(ConstString(symbol_name)), true);
-
- } else {
- callback(entry.recognizer_id, entry.recognizer->GetName(),
- entry.module.GetCString(), entry.symbols, false);
- }
- }
- }
-
- bool RemoveRecognizerWithID(uint32_t recognizer_id) {
- if (recognizer_id >= m_recognizers.size()) return false;
- if (m_recognizers[recognizer_id].deleted) return false;
- m_recognizers[recognizer_id].deleted = true;
- return true;
- }
+void StackFrameRecognizerManager::AddRecognizer(
+ StackFrameRecognizerSP recognizer, ConstString module,
+ llvm::ArrayRef<ConstString> symbols, bool first_instruction_only) {
+ m_recognizers.push_front({(uint32_t)m_recognizers.size(), recognizer, false,
+ module, RegularExpressionSP(), symbols,
+ RegularExpressionSP(), first_instruction_only});
+}
- void RemoveAllRecognizers() {
- m_recognizers.clear();
- }
+void StackFrameRecognizerManager::AddRecognizer(
+ StackFrameRecognizerSP recognizer, RegularExpressionSP module,
+ RegularExpressionSP symbol, bool first_instruction_only) {
+ m_recognizers.push_front({(uint32_t)m_recognizers.size(), recognizer, true,
+ ConstString(), module, std::vector<ConstString>(),
+ symbol, first_instruction_only});
+}
- StackFrameRecognizerSP GetRecognizerForFrame(StackFrameSP frame) {
- const SymbolContext &symctx = frame->GetSymbolContext(
- eSymbolContextModule | eSymbolContextFunction | eSymbolContextSymbol);
- ConstString function_name = symctx.GetFunctionName();
- ModuleSP module_sp = symctx.module_sp;
- if (!module_sp) return StackFrameRecognizerSP();
- ConstString module_name = module_sp->GetFileSpec().GetFilename();
- Symbol *symbol = symctx.symbol;
- if (!symbol) return StackFrameRecognizerSP();
- Address start_addr = symbol->GetAddress();
- Address current_addr = frame->GetFrameCodeAddress();
-
- for (auto entry : m_recognizers) {
- if (entry.deleted) continue;
- if (entry.module)
- if (entry.module != module_name) continue;
+void StackFrameRecognizerManager::ForEach(
+ const std::function<void(uint32_t, std::string, std::string,
+ llvm::ArrayRef<ConstString>, bool)> &callback) {
+ for (auto entry : m_recognizers) {
+ if (entry.is_regexp) {
+ std::string module_name;
+ std::string symbol_name;
if (entry.module_regexp)
- if (!entry.module_regexp->Execute(module_name.GetStringRef())) continue;
-
- if (!entry.symbols.empty())
- if (!llvm::is_contained(entry.symbols, function_name))
- continue;
-
+ module_name = entry.module_regexp->GetText().str();
if (entry.symbol_regexp)
- if (!entry.symbol_regexp->Execute(function_name.GetStringRef()))
- continue;
+ symbol_name = entry.symbol_regexp->GetText().str();
- if (entry.first_instruction_only)
- if (start_addr != current_addr) continue;
+ callback(entry.recognizer_id, entry.recognizer->GetName(), module_name,
+ llvm::makeArrayRef(ConstString(symbol_name)), true);
- return entry.recognizer;
+ } else {
+ callback(entry.recognizer_id, entry.recognizer->GetName(),
+ entry.module.GetCString(), entry.symbols, false);
}
- return StackFrameRecognizerSP();
}
-
- RecognizedStackFrameSP RecognizeFrame(StackFrameSP frame) {
- auto recognizer = GetRecognizerForFrame(frame);
- if (!recognizer) return RecognizedStackFrameSP();
- return recognizer->RecognizeFrame(frame);
- }
-
- private:
- struct RegisteredEntry {
- uint32_t recognizer_id;
- bool deleted;
- StackFrameRecognizerSP recognizer;
- bool is_regexp;
- ConstString module;
- RegularExpressionSP module_regexp;
- std::vector<ConstString> symbols;
- RegularExpressionSP symbol_regexp;
- bool first_instruction_only;
- };
-
- std::deque<RegisteredEntry> m_recognizers;
-};
-
-StackFrameRecognizerManagerImpl &GetStackFrameRecognizerManagerImpl() {
- static StackFrameRecognizerManagerImpl instance =
- StackFrameRecognizerManagerImpl();
- return instance;
}
-void StackFrameRecognizerManager::AddRecognizer(
- StackFrameRecognizerSP recognizer, ConstString module,
- llvm::ArrayRef<ConstString> symbols, bool first_instruction_only) {
- GetStackFrameRecognizerManagerImpl().AddRecognizer(
- recognizer, module, symbols, first_instruction_only);
+bool StackFrameRecognizerManager::RemoveRecognizerWithID(
+ uint32_t recognizer_id) {
+ if (recognizer_id >= m_recognizers.size())
+ return false;
+ auto found =
+ llvm::find_if(m_recognizers, [recognizer_id](const RegisteredEntry &e) {
+ return e.recognizer_id == recognizer_id;
+ });
+ if (found == m_recognizers.end())
+ return false;
+ m_recognizers.erase(found);
+ return true;
}
-void StackFrameRecognizerManager::AddRecognizer(
- StackFrameRecognizerSP recognizer, RegularExpressionSP module,
- RegularExpressionSP symbol, bool first_instruction_only) {
- GetStackFrameRecognizerManagerImpl().AddRecognizer(recognizer, module, symbol,
- first_instruction_only);
+void StackFrameRecognizerManager::RemoveAllRecognizers() {
+ m_recognizers.clear();
}
-void StackFrameRecognizerManager::ForEach(
- std::function<void(uint32_t recognized_id, std::string recognizer_name,
- std::string module, llvm::ArrayRef<ConstString> symbols,
- bool regexp)> const &callback) {
- GetStackFrameRecognizerManagerImpl().ForEach(callback);
-}
+StackFrameRecognizerSP
+StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) {
+ const SymbolContext &symctx = frame->GetSymbolContext(
+ eSymbolContextModule | eSymbolContextFunction | eSymbolContextSymbol);
+ ConstString function_name = symctx.GetFunctionName();
+ ModuleSP module_sp = symctx.module_sp;
+ if (!module_sp)
+ return StackFrameRecognizerSP();
+ ConstString module_name = module_sp->GetFileSpec().GetFilename();
+ Symbol *symbol = symctx.symbol;
+ if (!symbol)
+ return StackFrameRecognizerSP();
+ Address start_addr = symbol->GetAddress();
+ Address current_addr = frame->GetFrameCodeAddress();
-void StackFrameRecognizerManager::RemoveAllRecognizers() {
- GetStackFrameRecognizerManagerImpl().RemoveAllRecognizers();
-}
+ for (auto entry : m_recognizers) {
+ if (entry.module)
+ if (entry.module != module_name)
+ continue;
-bool StackFrameRecognizerManager::RemoveRecognizerWithID(uint32_t recognizer_id) {
- return GetStackFrameRecognizerManagerImpl().RemoveRecognizerWithID(recognizer_id);
-}
+ if (entry.module_regexp)
+ if (!entry.module_regexp->Execute(module_name.GetStringRef()))
+ continue;
-RecognizedStackFrameSP StackFrameRecognizerManager::RecognizeFrame(
- StackFrameSP frame) {
- return GetStackFrameRecognizerManagerImpl().RecognizeFrame(frame);
+ if (!entry.symbols.empty())
+ if (!llvm::is_contained(entry.symbols, function_name))
+ continue;
+
+ if (entry.symbol_regexp)
+ if (!entry.symbol_regexp->Execute(function_name.GetStringRef()))
+ continue;
+
+ if (entry.first_instruction_only)
+ if (start_addr != current_addr)
+ continue;
+
+ return entry.recognizer;
+ }
+ return StackFrameRecognizerSP();
}
-StackFrameRecognizerSP StackFrameRecognizerManager::GetRecognizerForFrame(
- lldb::StackFrameSP frame) {
- return GetStackFrameRecognizerManagerImpl().GetRecognizerForFrame(frame);
+RecognizedStackFrameSP
+StackFrameRecognizerManager::RecognizeFrame(StackFrameSP frame) {
+ auto recognizer = GetRecognizerForFrame(frame);
+ if (!recognizer)
+ return RecognizedStackFrameSP();
+ return recognizer->RecognizeFrame(frame);
}
diff --git a/contrib/llvm-project/lldb/source/Target/SystemRuntime.cpp b/contrib/llvm-project/lldb/source/Target/SystemRuntime.cpp
index cd3d8ba2c7b0..6d8a2ef55225 100644
--- a/contrib/llvm-project/lldb/source/Target/SystemRuntime.cpp
+++ b/contrib/llvm-project/lldb/source/Target/SystemRuntime.cpp
@@ -27,9 +27,7 @@ SystemRuntime *SystemRuntime::FindPlugin(Process *process) {
return nullptr;
}
-// SystemRuntime constructor
-SystemRuntime::SystemRuntime(Process *process)
- : m_process(process), m_types() {}
+SystemRuntime::SystemRuntime(Process *process) : Runtime(process), m_types() {}
SystemRuntime::~SystemRuntime() = default;
@@ -39,7 +37,7 @@ void SystemRuntime::DidLaunch() {}
void SystemRuntime::Detach() {}
-void SystemRuntime::ModulesDidLoad(ModuleList &module_list) {}
+void SystemRuntime::ModulesDidLoad(const ModuleList &module_list) {}
const std::vector<ConstString> &SystemRuntime::GetExtendedBacktraceTypes() {
return m_types;
diff --git a/contrib/llvm-project/lldb/source/Target/Target.cpp b/contrib/llvm-project/lldb/source/Target/Target.cpp
index 19d0c3d477eb..736864e021bb 100644
--- a/contrib/llvm-project/lldb/source/Target/Target.cpp
+++ b/contrib/llvm-project/lldb/source/Target/Target.cpp
@@ -27,9 +27,11 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Core/ValueObject.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Expression/REPL.h"
#include "lldb/Expression/UserExpression.h"
+#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/PosixApi.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -45,6 +47,7 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/StackFrameRecognizer.h"
#include "lldb/Target/SystemRuntime.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"
@@ -94,6 +97,8 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch,
m_source_manager_up(), m_stop_hooks(), m_stop_hook_next_id(0),
m_valid(true), m_suppress_stop_hooks(false),
m_is_dummy_target(is_dummy_target),
+ m_frame_recognizer_manager_up(
+ std::make_unique<StackFrameRecognizerManager>()),
m_stats_storage(static_cast<int>(StatisticKind::StatisticMax))
{
@@ -123,13 +128,10 @@ Target::~Target() {
DeleteCurrentProcess();
}
-void Target::PrimeFromDummyTarget(Target *target) {
- if (!target)
- return;
-
- m_stop_hooks = target->m_stop_hooks;
+void Target::PrimeFromDummyTarget(Target &target) {
+ m_stop_hooks = target.m_stop_hooks;
- for (const auto &breakpoint_sp : target->m_breakpoint_list.Breakpoints()) {
+ for (const auto &breakpoint_sp : target.m_breakpoint_list.Breakpoints()) {
if (breakpoint_sp->IsInternal())
continue;
@@ -138,11 +140,14 @@ void Target::PrimeFromDummyTarget(Target *target) {
AddBreakpoint(std::move(new_bp), false);
}
- for (auto bp_name_entry : target->m_breakpoint_names) {
+ for (auto bp_name_entry : target.m_breakpoint_names) {
BreakpointName *new_bp_name = new BreakpointName(*bp_name_entry.second);
AddBreakpointName(new_bp_name);
}
+
+ m_frame_recognizer_manager_up = std::make_unique<StackFrameRecognizerManager>(
+ *target.m_frame_recognizer_manager_up);
}
void Target::Dump(Stream *s, lldb::DescriptionLevel description_level) {
@@ -194,12 +199,13 @@ void Target::DeleteCurrentProcess() {
const lldb::ProcessSP &Target::CreateProcess(ListenerSP listener_sp,
llvm::StringRef plugin_name,
- const FileSpec *crash_file) {
+ const FileSpec *crash_file,
+ bool can_connect) {
if (!listener_sp)
listener_sp = GetDebugger().GetListener();
DeleteCurrentProcess();
m_process_sp = Process::FindPlugin(shared_from_this(), plugin_name,
- listener_sp, crash_file);
+ listener_sp, crash_file, can_connect);
return m_process_sp;
}
@@ -1394,9 +1400,7 @@ void Target::SetExecutableModule(ModuleSP &executable_sp,
ClearModules(false);
if (executable_sp) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat,
- "Target::SetExecutableModule (executable = '%s')",
+ LLDB_SCOPED_TIMERF("Target::SetExecutableModule (executable = '%s')",
executable_sp->GetFileSpec().GetPath().c_str());
const bool notify = true;
@@ -2290,27 +2294,29 @@ FunctionCaller *Target::GetFunctionCallerForLanguage(
return persistent_fn;
}
-UtilityFunction *
-Target::GetUtilityFunctionForLanguage(const char *text,
- lldb::LanguageType language,
- const char *name, Status &error) {
+llvm::Expected<std::unique_ptr<UtilityFunction>>
+Target::CreateUtilityFunction(std::string expression, std::string name,
+ lldb::LanguageType language,
+ ExecutionContext &exe_ctx) {
auto type_system_or_err = GetScratchTypeSystemForLanguage(language);
+ if (!type_system_or_err)
+ return type_system_or_err.takeError();
- if (auto err = type_system_or_err.takeError()) {
- error.SetErrorStringWithFormat(
- "Could not find type system for language %s: %s",
- Language::GetNameForLanguageType(language),
- llvm::toString(std::move(err)).c_str());
- return nullptr;
- }
-
- auto *utility_fn = type_system_or_err->GetUtilityFunction(text, name);
+ std::unique_ptr<UtilityFunction> utility_fn =
+ type_system_or_err->CreateUtilityFunction(std::move(expression),
+ std::move(name));
if (!utility_fn)
- error.SetErrorStringWithFormat(
- "Could not create an expression for language %s",
- Language::GetNameForLanguageType(language));
+ return llvm::make_error<llvm::StringError>(
+ llvm::StringRef("Could not create an expression for language") +
+ Language::GetNameForLanguageType(language),
+ llvm::inconvertibleErrorCode());
- return utility_fn;
+ DiagnosticManager diagnostics;
+ if (!utility_fn->Install(diagnostics, exe_ctx))
+ return llvm::make_error<llvm::StringError>(diagnostics.GetString(),
+ llvm::inconvertibleErrorCode());
+
+ return std::move(utility_fn);
}
void Target::SettingsInitialize() { Process::SettingsInitialize(); }
@@ -2532,13 +2538,28 @@ ClangModulesDeclVendor *Target::GetClangModulesDeclVendor() {
return m_clang_modules_decl_vendor_up.get();
}
-Target::StopHookSP Target::CreateStopHook() {
+Target::StopHookSP Target::CreateStopHook(StopHook::StopHookKind kind) {
lldb::user_id_t new_uid = ++m_stop_hook_next_id;
- Target::StopHookSP stop_hook_sp(new StopHook(shared_from_this(), new_uid));
+ Target::StopHookSP stop_hook_sp;
+ switch (kind) {
+ case StopHook::StopHookKind::CommandBased:
+ stop_hook_sp.reset(new StopHookCommandLine(shared_from_this(), new_uid));
+ break;
+ case StopHook::StopHookKind::ScriptBased:
+ stop_hook_sp.reset(new StopHookScripted(shared_from_this(), new_uid));
+ break;
+ }
m_stop_hooks[new_uid] = stop_hook_sp;
return stop_hook_sp;
}
+void Target::UndoCreateStopHook(lldb::user_id_t user_id) {
+ if (!RemoveStopHookByID(user_id))
+ return;
+ if (user_id == m_stop_hook_next_id)
+ m_stop_hook_next_id--;
+}
+
bool Target::RemoveStopHookByID(lldb::user_id_t user_id) {
size_t num_removed = m_stop_hooks.erase(user_id);
return (num_removed != 0);
@@ -2574,45 +2595,39 @@ void Target::SetAllStopHooksActiveState(bool active_state) {
}
}
-void Target::RunStopHooks() {
+bool Target::RunStopHooks() {
if (m_suppress_stop_hooks)
- return;
+ return false;
if (!m_process_sp)
- return;
+ return false;
// Somebody might have restarted the process:
+ // Still return false, the return value is about US restarting the target.
if (m_process_sp->GetState() != eStateStopped)
- return;
+ return false;
// <rdar://problem/12027563> make sure we check that we are not stopped
// because of us running a user expression since in that case we do not want
// to run the stop-hooks
if (m_process_sp->GetModIDRef().IsLastResumeForUserExpression())
- return;
+ return false;
if (m_stop_hooks.empty())
- return;
-
- StopHookCollection::iterator pos, end = m_stop_hooks.end();
+ return false;
// If there aren't any active stop hooks, don't bother either.
- // Also see if any of the active hooks want to auto-continue.
bool any_active_hooks = false;
- bool auto_continue = false;
for (auto hook : m_stop_hooks) {
if (hook.second->IsActive()) {
any_active_hooks = true;
- auto_continue |= hook.second->GetAutoContinue();
+ break;
}
}
if (!any_active_hooks)
- return;
-
- CommandReturnObject result(m_debugger.GetUseColor());
+ return false;
std::vector<ExecutionContext> exc_ctx_with_reasons;
- std::vector<SymbolContext> sym_ctx_with_reasons;
ThreadList &cur_threadlist = m_process_sp->GetThreadList();
size_t num_threads = cur_threadlist.GetSize();
@@ -2620,103 +2635,127 @@ void Target::RunStopHooks() {
lldb::ThreadSP cur_thread_sp = cur_threadlist.GetThreadAtIndex(i);
if (cur_thread_sp->ThreadStoppedForAReason()) {
lldb::StackFrameSP cur_frame_sp = cur_thread_sp->GetStackFrameAtIndex(0);
- exc_ctx_with_reasons.push_back(ExecutionContext(
- m_process_sp.get(), cur_thread_sp.get(), cur_frame_sp.get()));
- sym_ctx_with_reasons.push_back(
- cur_frame_sp->GetSymbolContext(eSymbolContextEverything));
+ exc_ctx_with_reasons.emplace_back(m_process_sp.get(), cur_thread_sp.get(),
+ cur_frame_sp.get());
}
}
// If no threads stopped for a reason, don't run the stop-hooks.
size_t num_exe_ctx = exc_ctx_with_reasons.size();
if (num_exe_ctx == 0)
- return;
+ return false;
- result.SetImmediateOutputStream(m_debugger.GetAsyncOutputStream());
- result.SetImmediateErrorStream(m_debugger.GetAsyncErrorStream());
+ StreamSP output_sp = m_debugger.GetAsyncOutputStream();
- bool keep_going = true;
+ bool auto_continue = false;
bool hooks_ran = false;
bool print_hook_header = (m_stop_hooks.size() != 1);
bool print_thread_header = (num_exe_ctx != 1);
- bool did_restart = false;
+ bool should_stop = false;
+ bool somebody_restarted = false;
- for (pos = m_stop_hooks.begin(); keep_going && pos != end; pos++) {
- // result.Clear();
- StopHookSP cur_hook_sp = (*pos).second;
+ for (auto stop_entry : m_stop_hooks) {
+ StopHookSP cur_hook_sp = stop_entry.second;
if (!cur_hook_sp->IsActive())
continue;
bool any_thread_matched = false;
- for (size_t i = 0; keep_going && i < num_exe_ctx; i++) {
- if ((cur_hook_sp->GetSpecifier() == nullptr ||
- cur_hook_sp->GetSpecifier()->SymbolContextMatches(
- sym_ctx_with_reasons[i])) &&
- (cur_hook_sp->GetThreadSpecifier() == nullptr ||
- cur_hook_sp->GetThreadSpecifier()->ThreadPassesBasicTests(
- exc_ctx_with_reasons[i].GetThreadRef()))) {
- if (!hooks_ran) {
- hooks_ran = true;
- }
- if (print_hook_header && !any_thread_matched) {
- const char *cmd =
- (cur_hook_sp->GetCommands().GetSize() == 1
- ? cur_hook_sp->GetCommands().GetStringAtIndex(0)
- : nullptr);
- if (cmd)
- result.AppendMessageWithFormat("\n- Hook %" PRIu64 " (%s)\n",
- cur_hook_sp->GetID(), cmd);
- else
- result.AppendMessageWithFormat("\n- Hook %" PRIu64 "\n",
- cur_hook_sp->GetID());
- any_thread_matched = true;
- }
+ for (auto exc_ctx : exc_ctx_with_reasons) {
+ // We detect somebody restarted in the stop-hook loop, and broke out of
+ // that loop back to here. So break out of here too.
+ if (somebody_restarted)
+ break;
- if (print_thread_header)
- result.AppendMessageWithFormat(
- "-- Thread %d\n",
- exc_ctx_with_reasons[i].GetThreadPtr()->GetIndexID());
-
- CommandInterpreterRunOptions options;
- options.SetStopOnContinue(true);
- options.SetStopOnError(true);
- options.SetEchoCommands(false);
- options.SetPrintResults(true);
- options.SetPrintErrors(true);
- options.SetAddToHistory(false);
-
- // Force Async:
- bool old_async = GetDebugger().GetAsyncExecution();
- GetDebugger().SetAsyncExecution(true);
- GetDebugger().GetCommandInterpreter().HandleCommands(
- cur_hook_sp->GetCommands(), &exc_ctx_with_reasons[i], options,
- result);
- GetDebugger().SetAsyncExecution(old_async);
- // If the command started the target going again, we should bag out of
- // running the stop hooks.
- if ((result.GetStatus() == eReturnStatusSuccessContinuingNoResult) ||
- (result.GetStatus() == eReturnStatusSuccessContinuingResult)) {
- // But only complain if there were more stop hooks to do:
- StopHookCollection::iterator tmp = pos;
- if (++tmp != end)
- result.AppendMessageWithFormat(
- "\nAborting stop hooks, hook %" PRIu64
- " set the program running.\n"
- " Consider using '-G true' to make "
- "stop hooks auto-continue.\n",
- cur_hook_sp->GetID());
- keep_going = false;
- did_restart = true;
- }
+ if (!cur_hook_sp->ExecutionContextPasses(exc_ctx))
+ continue;
+
+ // We only consult the auto-continue for a stop hook if it matched the
+ // specifier.
+ auto_continue |= cur_hook_sp->GetAutoContinue();
+
+ if (!hooks_ran)
+ hooks_ran = true;
+
+ if (print_hook_header && !any_thread_matched) {
+ StreamString s;
+ cur_hook_sp->GetDescription(&s, eDescriptionLevelBrief);
+ if (s.GetSize() != 0)
+ output_sp->Printf("\n- Hook %" PRIu64 " (%s)\n", cur_hook_sp->GetID(),
+ s.GetData());
+ else
+ output_sp->Printf("\n- Hook %" PRIu64 "\n", cur_hook_sp->GetID());
+ any_thread_matched = true;
+ }
+
+ if (print_thread_header)
+ output_sp->Printf("-- Thread %d\n",
+ exc_ctx.GetThreadPtr()->GetIndexID());
+
+ StopHook::StopHookResult this_result =
+ cur_hook_sp->HandleStop(exc_ctx, output_sp);
+ bool this_should_stop = true;
+
+ switch (this_result) {
+ case StopHook::StopHookResult::KeepStopped:
+ // If this hook is set to auto-continue that should override the
+ // HandleStop result...
+ if (cur_hook_sp->GetAutoContinue())
+ this_should_stop = false;
+ else
+ this_should_stop = true;
+
+ break;
+ case StopHook::StopHookResult::RequestContinue:
+ this_should_stop = false;
+ break;
+ case StopHook::StopHookResult::AlreadyContinued:
+ // We don't have a good way to prohibit people from restarting the
+ // target willy nilly in a stop hook. If the hook did so, give a
+ // gentle suggestion here and bag out if the hook processing.
+ output_sp->Printf("\nAborting stop hooks, hook %" PRIu64
+ " set the program running.\n"
+ " Consider using '-G true' to make "
+ "stop hooks auto-continue.\n",
+ cur_hook_sp->GetID());
+ somebody_restarted = true;
+ break;
}
+ // If we're already restarted, stop processing stop hooks.
+ // FIXME: if we are doing non-stop mode for real, we would have to
+ // check that OUR thread was restarted, otherwise we should keep
+ // processing stop hooks.
+ if (somebody_restarted)
+ break;
+
+ // If anybody wanted to stop, we should all stop.
+ if (!should_stop)
+ should_stop = this_should_stop;
}
}
+
+ output_sp->Flush();
+
+ // If one of the commands in the stop hook already restarted the target,
+ // report that fact.
+ if (somebody_restarted)
+ return true;
+
// Finally, if auto-continue was requested, do it now:
- if (!did_restart && auto_continue)
- m_process_sp->PrivateResume();
+ // We only compute should_stop against the hook results if a hook got to run
+ // which is why we have to do this conjoint test.
+ if ((hooks_ran && !should_stop) || auto_continue) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Status error = m_process_sp->PrivateResume();
+ if (error.Success()) {
+ LLDB_LOG(log, "Resuming from RunStopHooks");
+ return true;
+ } else {
+ LLDB_LOG(log, "Resuming from RunStopHooks failed: {0}", error);
+ return false;
+ }
+ }
- result.GetImmediateOutputStream()->Flush();
- result.GetImmediateErrorStream()->Flush();
+ return false;
}
const TargetPropertiesSP &Target::GetGlobalProperties() {
@@ -2935,7 +2974,7 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
} else {
// Use a Process plugin to construct the process.
const char *plugin_name = launch_info.GetProcessPluginName();
- CreateProcess(launch_info.GetListener(), plugin_name, nullptr);
+ CreateProcess(launch_info.GetListener(), plugin_name, nullptr, false);
}
// Since we didn't have a platform launch the process, launch it here.
@@ -2943,80 +2982,79 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
error = m_process_sp->Launch(launch_info);
}
- if (!m_process_sp) {
- if (error.Success())
- error.SetErrorString("failed to launch or debug process");
+ if (!m_process_sp && error.Success())
+ error.SetErrorString("failed to launch or debug process");
+
+ if (!error.Success())
return error;
- }
- if (error.Success()) {
- if (synchronous_execution ||
- !launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) {
- ListenerSP hijack_listener_sp(launch_info.GetHijackListener());
- if (!hijack_listener_sp) {
- hijack_listener_sp =
- Listener::MakeListener("lldb.Target.Launch.hijack");
- launch_info.SetHijackListener(hijack_listener_sp);
- m_process_sp->HijackProcessEvents(hijack_listener_sp);
- }
+ auto at_exit =
+ llvm::make_scope_exit([&]() { m_process_sp->RestoreProcessEvents(); });
- StateType state = m_process_sp->WaitForProcessToStop(
- llvm::None, nullptr, false, hijack_listener_sp, nullptr);
-
- if (state == eStateStopped) {
- if (!launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) {
- if (synchronous_execution) {
- // Now we have handled the stop-from-attach, and we are just
- // switching to a synchronous resume. So we should switch to the
- // SyncResume hijacker.
- m_process_sp->RestoreProcessEvents();
- m_process_sp->ResumeSynchronous(stream);
- } else {
- m_process_sp->RestoreProcessEvents();
- error = m_process_sp->PrivateResume();
- }
- if (!error.Success()) {
- Status error2;
- error2.SetErrorStringWithFormat(
- "process resume at entry point failed: %s", error.AsCString());
- error = error2;
- }
- }
- } else if (state == eStateExited) {
- bool with_shell = !!launch_info.GetShell();
- const int exit_status = m_process_sp->GetExitStatus();
- const char *exit_desc = m_process_sp->GetExitDescription();
-#define LAUNCH_SHELL_MESSAGE \
- "\n'r' and 'run' are aliases that default to launching through a " \
- "shell.\nTry launching without going through a shell by using 'process " \
- "launch'."
- if (exit_desc && exit_desc[0]) {
- if (with_shell)
- error.SetErrorStringWithFormat(
- "process exited with status %i (%s)" LAUNCH_SHELL_MESSAGE,
- exit_status, exit_desc);
- else
- error.SetErrorStringWithFormat("process exited with status %i (%s)",
- exit_status, exit_desc);
- } else {
- if (with_shell)
- error.SetErrorStringWithFormat(
- "process exited with status %i" LAUNCH_SHELL_MESSAGE,
- exit_status);
- else
- error.SetErrorStringWithFormat("process exited with status %i",
- exit_status);
- }
- } else {
- error.SetErrorStringWithFormat(
- "initial process state wasn't stopped: %s", StateAsCString(state));
- }
+ if (!synchronous_execution &&
+ launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
+ return error;
+
+ ListenerSP hijack_listener_sp(launch_info.GetHijackListener());
+ if (!hijack_listener_sp) {
+ hijack_listener_sp = Listener::MakeListener("lldb.Target.Launch.hijack");
+ launch_info.SetHijackListener(hijack_listener_sp);
+ m_process_sp->HijackProcessEvents(hijack_listener_sp);
+ }
+
+ switch (m_process_sp->WaitForProcessToStop(llvm::None, nullptr, false,
+ hijack_listener_sp, nullptr)) {
+ case eStateStopped: {
+ if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
+ break;
+ if (synchronous_execution) {
+ // Now we have handled the stop-from-attach, and we are just
+ // switching to a synchronous resume. So we should switch to the
+ // SyncResume hijacker.
+ m_process_sp->RestoreProcessEvents();
+ m_process_sp->ResumeSynchronous(stream);
+ } else {
+ m_process_sp->RestoreProcessEvents();
+ error = m_process_sp->PrivateResume();
+ }
+ if (!error.Success()) {
+ Status error2;
+ error2.SetErrorStringWithFormat(
+ "process resume at entry point failed: %s", error.AsCString());
+ error = error2;
}
- m_process_sp->RestoreProcessEvents();
+ } break;
+ case eStateExited: {
+ bool with_shell = !!launch_info.GetShell();
+ const int exit_status = m_process_sp->GetExitStatus();
+ const char *exit_desc = m_process_sp->GetExitDescription();
+ std::string desc;
+ if (exit_desc && exit_desc[0])
+ desc = " (" + std::string(exit_desc) + ')';
+ if (with_shell)
+ error.SetErrorStringWithFormat(
+ "process exited with status %i%s\n"
+ "'r' and 'run' are aliases that default to launching through a "
+ "shell.\n"
+ "Try launching without going through a shell by using "
+ "'process launch'.",
+ exit_status, desc.c_str());
+ else
+ error.SetErrorStringWithFormat("process exited with status %i%s",
+ exit_status, desc.c_str());
+ } break;
+ default:
+ error.SetErrorStringWithFormat("initial process state wasn't stopped: %s",
+ StateAsCString(state));
+ break;
}
return error;
}
+void Target::SetTrace(const TraceSP &trace_sp) { m_trace_sp = trace_sp; }
+
+const TraceSP &Target::GetTrace() { return m_trace_sp; }
+
Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) {
auto state = eStateInvalid;
auto process_sp = GetProcessSP();
@@ -3064,7 +3102,7 @@ Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) {
const char *plugin_name = attach_info.GetProcessPluginName();
process_sp =
CreateProcess(attach_info.GetListenerForProcess(GetDebugger()),
- plugin_name, nullptr);
+ plugin_name, nullptr, false);
if (process_sp == nullptr) {
error.SetErrorStringWithFormat(
"failed to create process using plugin %s",
@@ -3181,20 +3219,17 @@ void Target::FinalizeFileActions(ProcessLaunchInfo &info) {
// Target::StopHook
Target::StopHook::StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid)
- : UserID(uid), m_target_sp(target_sp), m_commands(), m_specifier_sp(),
+ : UserID(uid), m_target_sp(target_sp), m_specifier_sp(),
m_thread_spec_up() {}
Target::StopHook::StopHook(const StopHook &rhs)
: UserID(rhs.GetID()), m_target_sp(rhs.m_target_sp),
- m_commands(rhs.m_commands), m_specifier_sp(rhs.m_specifier_sp),
- m_thread_spec_up(), m_active(rhs.m_active),
- m_auto_continue(rhs.m_auto_continue) {
+ m_specifier_sp(rhs.m_specifier_sp), m_thread_spec_up(),
+ m_active(rhs.m_active), m_auto_continue(rhs.m_auto_continue) {
if (rhs.m_thread_spec_up)
m_thread_spec_up = std::make_unique<ThreadSpec>(*rhs.m_thread_spec_up);
}
-Target::StopHook::~StopHook() = default;
-
void Target::StopHook::SetSpecifier(SymbolContextSpecifier *specifier) {
m_specifier_sp.reset(specifier);
}
@@ -3203,8 +3238,31 @@ void Target::StopHook::SetThreadSpecifier(ThreadSpec *specifier) {
m_thread_spec_up.reset(specifier);
}
+bool Target::StopHook::ExecutionContextPasses(const ExecutionContext &exc_ctx) {
+ SymbolContextSpecifier *specifier = GetSpecifier();
+ if (!specifier)
+ return true;
+
+ bool will_run = true;
+ if (exc_ctx.GetFramePtr())
+ will_run = GetSpecifier()->SymbolContextMatches(
+ exc_ctx.GetFramePtr()->GetSymbolContext(eSymbolContextEverything));
+ if (will_run && GetThreadSpecifier() != nullptr)
+ will_run =
+ GetThreadSpecifier()->ThreadPassesBasicTests(exc_ctx.GetThreadRef());
+
+ return will_run;
+}
+
void Target::StopHook::GetDescription(Stream *s,
lldb::DescriptionLevel level) const {
+
+ // For brief descriptions, only print the subclass description:
+ if (level == eDescriptionLevelBrief) {
+ GetSubclassDescription(s, level);
+ return;
+ }
+
unsigned indent_level = s->GetIndentLevel();
s->SetIndentLevel(indent_level + 2);
@@ -3235,15 +3293,155 @@ void Target::StopHook::GetDescription(Stream *s,
s->PutCString("\n");
s->SetIndentLevel(indent_level + 2);
}
+ GetSubclassDescription(s, level);
+}
+void Target::StopHookCommandLine::GetSubclassDescription(
+ Stream *s, lldb::DescriptionLevel level) const {
+ // The brief description just prints the first command.
+ if (level == eDescriptionLevelBrief) {
+ if (m_commands.GetSize() == 1)
+ s->PutCString(m_commands.GetStringAtIndex(0));
+ return;
+ }
s->Indent("Commands: \n");
- s->SetIndentLevel(indent_level + 4);
+ s->SetIndentLevel(s->GetIndentLevel() + 4);
uint32_t num_commands = m_commands.GetSize();
for (uint32_t i = 0; i < num_commands; i++) {
s->Indent(m_commands.GetStringAtIndex(i));
s->PutCString("\n");
}
- s->SetIndentLevel(indent_level);
+ s->SetIndentLevel(s->GetIndentLevel() - 4);
+}
+
+// Target::StopHookCommandLine
+void Target::StopHookCommandLine::SetActionFromString(const std::string &string) {
+ GetCommands().SplitIntoLines(string);
+}
+
+void Target::StopHookCommandLine::SetActionFromStrings(
+ const std::vector<std::string> &strings) {
+ for (auto string : strings)
+ GetCommands().AppendString(string.c_str());
+}
+
+Target::StopHook::StopHookResult
+Target::StopHookCommandLine::HandleStop(ExecutionContext &exc_ctx,
+ StreamSP output_sp) {
+ assert(exc_ctx.GetTargetPtr() && "Can't call PerformAction on a context "
+ "with no target");
+
+ if (!m_commands.GetSize())
+ return StopHookResult::KeepStopped;
+
+ CommandReturnObject result(false);
+ result.SetImmediateOutputStream(output_sp);
+ result.SetInteractive(false);
+ Debugger &debugger = exc_ctx.GetTargetPtr()->GetDebugger();
+ CommandInterpreterRunOptions options;
+ options.SetStopOnContinue(true);
+ options.SetStopOnError(true);
+ options.SetEchoCommands(false);
+ options.SetPrintResults(true);
+ options.SetPrintErrors(true);
+ options.SetAddToHistory(false);
+
+ // Force Async:
+ bool old_async = debugger.GetAsyncExecution();
+ debugger.SetAsyncExecution(true);
+ debugger.GetCommandInterpreter().HandleCommands(GetCommands(), &exc_ctx,
+ options, result);
+ debugger.SetAsyncExecution(old_async);
+ lldb::ReturnStatus status = result.GetStatus();
+ if (status == eReturnStatusSuccessContinuingNoResult ||
+ status == eReturnStatusSuccessContinuingResult)
+ return StopHookResult::AlreadyContinued;
+ return StopHookResult::KeepStopped;
+}
+
+// Target::StopHookScripted
+Status Target::StopHookScripted::SetScriptCallback(
+ std::string class_name, StructuredData::ObjectSP extra_args_sp) {
+ Status error;
+
+ ScriptInterpreter *script_interp =
+ GetTarget()->GetDebugger().GetScriptInterpreter();
+ if (!script_interp) {
+ error.SetErrorString("No script interpreter installed.");
+ return error;
+ }
+
+ m_class_name = class_name;
+
+ m_extra_args = new StructuredDataImpl();
+
+ if (extra_args_sp)
+ m_extra_args->SetObjectSP(extra_args_sp);
+
+ m_implementation_sp = script_interp->CreateScriptedStopHook(
+ GetTarget(), m_class_name.c_str(), m_extra_args, error);
+
+ return error;
+}
+
+Target::StopHook::StopHookResult
+Target::StopHookScripted::HandleStop(ExecutionContext &exc_ctx,
+ StreamSP output_sp) {
+ assert(exc_ctx.GetTargetPtr() && "Can't call HandleStop on a context "
+ "with no target");
+
+ ScriptInterpreter *script_interp =
+ GetTarget()->GetDebugger().GetScriptInterpreter();
+ if (!script_interp)
+ return StopHookResult::KeepStopped;
+
+ bool should_stop = script_interp->ScriptedStopHookHandleStop(
+ m_implementation_sp, exc_ctx, output_sp);
+
+ return should_stop ? StopHookResult::KeepStopped
+ : StopHookResult::RequestContinue;
+}
+
+void Target::StopHookScripted::GetSubclassDescription(
+ Stream *s, lldb::DescriptionLevel level) const {
+ if (level == eDescriptionLevelBrief) {
+ s->PutCString(m_class_name);
+ return;
+ }
+ s->Indent("Class:");
+ s->Printf("%s\n", m_class_name.c_str());
+
+ // Now print the extra args:
+ // FIXME: We should use StructuredData.GetDescription on the m_extra_args
+ // but that seems to rely on some printing plugin that doesn't exist.
+ if (!m_extra_args->IsValid())
+ return;
+ StructuredData::ObjectSP object_sp = m_extra_args->GetObjectSP();
+ if (!object_sp || !object_sp->IsValid())
+ return;
+
+ StructuredData::Dictionary *as_dict = object_sp->GetAsDictionary();
+ if (!as_dict || !as_dict->IsValid())
+ return;
+
+ uint32_t num_keys = as_dict->GetSize();
+ if (num_keys == 0)
+ return;
+
+ s->Indent("Args:\n");
+ s->SetIndentLevel(s->GetIndentLevel() + 4);
+
+ auto print_one_element = [&s](ConstString key,
+ StructuredData::Object *object) {
+ s->Indent();
+ s->Printf("%s : %s\n", key.GetCString(),
+ object->GetStringValue().str().c_str());
+ return true;
+ };
+
+ as_dict->ForEach(print_one_element);
+
+ s->SetIndentLevel(s->GetIndentLevel() - 4);
}
static constexpr OptionEnumValueElement g_dynamic_value_types[] = {
@@ -3316,6 +3514,28 @@ static constexpr OptionEnumValueElement g_x86_dis_flavor_value_types[] = {
},
};
+static constexpr OptionEnumValueElement g_import_std_module_value_types[] = {
+ {
+ eImportStdModuleFalse,
+ "false",
+ "Never import the 'std' C++ module in the expression parser.",
+ },
+ {
+ eImportStdModuleFallback,
+ "fallback",
+ "Retry evaluating expressions with an imported 'std' C++ module if they"
+ " failed to parse without the module. This allows evaluating more "
+ "complex expressions involving C++ standard library types."
+ },
+ {
+ eImportStdModuleTrue,
+ "true",
+ "Always import the 'std' C++ module. This allows evaluating more "
+ "complex expressions involving C++ standard library types. This feature"
+ " is experimental."
+ },
+};
+
static constexpr OptionEnumValueElement g_hex_immediate_style_values[] = {
{
Disassembler::eHexStyleC,
@@ -3478,6 +3698,8 @@ TargetProperties::TargetProperties(Target *target)
m_collection_sp->SetValueChangedCallback(
ePropertyDisableASLR, [this] { DisableASLRValueChangedCallback(); });
m_collection_sp->SetValueChangedCallback(
+ ePropertyInheritTCC, [this] { InheritTCCValueChangedCallback(); });
+ m_collection_sp->SetValueChangedCallback(
ePropertyDisableSTDIO, [this] { DisableSTDIOValueChangedCallback(); });
m_experimental_properties_up =
@@ -3515,6 +3737,7 @@ void TargetProperties::UpdateLaunchInfoFromProperties() {
ErrorPathValueChangedCallback();
DetachOnErrorValueChangedCallback();
DisableASLRValueChangedCallback();
+ InheritTCCValueChangedCallback();
DisableSTDIOValueChangedCallback();
}
@@ -3597,6 +3820,17 @@ void TargetProperties::SetDisableASLR(bool b) {
m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}
+bool TargetProperties::GetInheritTCC() const {
+ const uint32_t idx = ePropertyInheritTCC;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_target_properties[idx].default_uint_value != 0);
+}
+
+void TargetProperties::SetInheritTCC(bool b) {
+ const uint32_t idx = ePropertyInheritTCC;
+ m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+}
+
bool TargetProperties::GetDetachOnError() const {
const uint32_t idx = ePropertyDetachOnError;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
@@ -3755,10 +3989,10 @@ bool TargetProperties::GetEnableAutoImportClangModules() const {
nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
-bool TargetProperties::GetEnableImportStdModule() const {
+ImportStdModule TargetProperties::GetImportStdModule() const {
const uint32_t idx = ePropertyImportStdModule;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_target_properties[idx].default_uint_value != 0);
+ return (ImportStdModule)m_collection_sp->GetPropertyAtIndexAsEnumeration(
+ nullptr, idx, g_target_properties[idx].default_uint_value);
}
bool TargetProperties::GetEnableAutoApplyFixIts() const {
@@ -3869,6 +4103,12 @@ llvm::StringRef TargetProperties::GetExpressionPrefixContents() {
return "";
}
+uint64_t TargetProperties::GetExprErrorLimit() const {
+ const uint32_t idx = ePropertyExprErrorLimit;
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(
+ nullptr, idx, g_target_properties[idx].default_uint_value);
+}
+
bool TargetProperties::GetBreakpointsConsultPlatformAvoidList() {
const uint32_t idx = ePropertyBreakpointUseAvoidList;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
@@ -3988,6 +4228,8 @@ void TargetProperties::SetProcessLaunchInfo(
}
SetDetachOnError(launch_info.GetFlags().Test(lldb::eLaunchFlagDetachOnError));
SetDisableASLR(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableASLR));
+ SetInheritTCC(
+ launch_info.GetFlags().Test(lldb::eLaunchFlagInheritTCCFromParent));
SetDisableSTDIO(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableSTDIO));
}
@@ -4051,6 +4293,13 @@ void TargetProperties::DisableASLRValueChangedCallback() {
m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableASLR);
}
+void TargetProperties::InheritTCCValueChangedCallback() {
+ if (GetInheritTCC())
+ m_launch_info.GetFlags().Set(lldb::eLaunchFlagInheritTCCFromParent);
+ else
+ m_launch_info.GetFlags().Clear(lldb::eLaunchFlagInheritTCCFromParent);
+}
+
void TargetProperties::DisableSTDIOValueChangedCallback() {
if (GetDisableSTDIO())
m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableSTDIO);
diff --git a/contrib/llvm-project/lldb/source/Target/TargetList.cpp b/contrib/llvm-project/lldb/source/Target/TargetList.cpp
index 3974cb5de419..1e5856dd0b22 100644
--- a/contrib/llvm-project/lldb/source/Target/TargetList.cpp
+++ b/contrib/llvm-project/lldb/source/Target/TargetList.cpp
@@ -42,21 +42,19 @@ TargetList::TargetList(Debugger &debugger)
CheckInWithManager();
}
-// Destructor
-TargetList::~TargetList() {
- std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
- m_target_list.clear();
-}
-
Status TargetList::CreateTarget(Debugger &debugger,
llvm::StringRef user_exe_path,
llvm::StringRef triple_str,
LoadDependentFiles load_dependent_files,
const OptionGroupPlatform *platform_options,
TargetSP &target_sp) {
- return CreateTargetInternal(debugger, user_exe_path, triple_str,
- load_dependent_files, platform_options, target_sp,
- false);
+ auto result = TargetList::CreateTargetInternal(
+ debugger, user_exe_path, triple_str, load_dependent_files,
+ platform_options, target_sp);
+
+ if (target_sp && result.Success())
+ AddTargetInternal(target_sp, /*do_select*/ true);
+ return result;
}
Status TargetList::CreateTarget(Debugger &debugger,
@@ -64,66 +62,72 @@ Status TargetList::CreateTarget(Debugger &debugger,
const ArchSpec &specified_arch,
LoadDependentFiles load_dependent_files,
PlatformSP &platform_sp, TargetSP &target_sp) {
- return CreateTargetInternal(debugger, user_exe_path, specified_arch,
- load_dependent_files, platform_sp, target_sp,
- false);
+ auto result = TargetList::CreateTargetInternal(
+ debugger, user_exe_path, specified_arch, load_dependent_files,
+ platform_sp, target_sp);
+
+ if (target_sp && result.Success())
+ AddTargetInternal(target_sp, /*do_select*/ true);
+ return result;
}
Status TargetList::CreateTargetInternal(
Debugger &debugger, llvm::StringRef user_exe_path,
llvm::StringRef triple_str, LoadDependentFiles load_dependent_files,
- const OptionGroupPlatform *platform_options, TargetSP &target_sp,
- bool is_dummy_target) {
+ const OptionGroupPlatform *platform_options, TargetSP &target_sp) {
Status error;
- PlatformSP platform_sp;
- // This is purposely left empty unless it is specified by triple_cstr. If not
- // initialized via triple_cstr, then the currently selected platform will set
- // the architecture correctly.
+ // Let's start by looking at the selected platform.
+ PlatformSP platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
+
+ // This variable corresponds to the architecture specified by the triple
+ // string. If that string was empty the currently selected platform will
+ // determine the architecture.
const ArchSpec arch(triple_str);
- if (!triple_str.empty()) {
- if (!arch.IsValid()) {
- error.SetErrorStringWithFormat("invalid triple '%s'",
- triple_str.str().c_str());
- return error;
- }
+ if (!triple_str.empty() && !arch.IsValid()) {
+ error.SetErrorStringWithFormat("invalid triple '%s'",
+ triple_str.str().c_str());
+ return error;
}
ArchSpec platform_arch(arch);
- bool prefer_platform_arch = false;
-
- CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
-
- // let's see if there is already an existing platform before we go creating
- // another...
- platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
+ // Create a new platform if a platform was specified in the platform options
+ // and doesn't match the selected platform.
+ if (platform_options && platform_options->PlatformWasSpecified() &&
+ !platform_options->PlatformMatches(platform_sp)) {
+ const bool select_platform = true;
+ platform_sp = platform_options->CreatePlatformWithOptions(
+ debugger.GetCommandInterpreter(), arch, select_platform, error,
+ platform_arch);
+ if (!platform_sp)
+ return error;
+ }
- if (platform_options && platform_options->PlatformWasSpecified()) {
- // Create a new platform if it doesn't match the selected platform
- if (!platform_options->PlatformMatches(platform_sp)) {
- const bool select_platform = true;
- platform_sp = platform_options->CreatePlatformWithOptions(
- interpreter, arch, select_platform, error, platform_arch);
- if (!platform_sp)
- return error;
+ bool prefer_platform_arch = false;
+ auto update_platform_arch = [&](const ArchSpec &module_arch) {
+ // If the OS or vendor weren't specified, then adopt the module's
+ // architecture so that the platform matching can be more accurate.
+ if (!platform_arch.TripleOSWasSpecified() ||
+ !platform_arch.TripleVendorWasSpecified()) {
+ prefer_platform_arch = true;
+ platform_arch = module_arch;
}
- }
+ };
if (!user_exe_path.empty()) {
- ModuleSpecList module_specs;
- ModuleSpec module_spec;
- module_spec.GetFileSpec().SetFile(user_exe_path, FileSpec::Style::native);
+ ModuleSpec module_spec(FileSpec(user_exe_path, FileSpec::Style::native));
FileSystem::Instance().Resolve(module_spec.GetFileSpec());
-
// Resolve the executable in case we are given a path to a application
- // bundle like a .app bundle on MacOSX
+ // bundle like a .app bundle on MacOSX.
Host::ResolveExecutableInBundle(module_spec.GetFileSpec());
lldb::offset_t file_offset = 0;
lldb::offset_t file_size = 0;
+ ModuleSpecList module_specs;
const size_t num_specs = ObjectFile::GetModuleSpecifications(
module_spec.GetFileSpec(), file_offset, file_size, module_specs);
+
if (num_specs > 0) {
ModuleSpec matching_module_spec;
@@ -134,12 +138,8 @@ Status TargetList::CreateTargetInternal(
matching_module_spec.GetArchitecture())) {
// If the OS or vendor weren't specified, then adopt the module's
// architecture so that the platform matching can be more
- // accurate
- if (!platform_arch.TripleOSWasSpecified() ||
- !platform_arch.TripleVendorWasSpecified()) {
- prefer_platform_arch = true;
- platform_arch = matching_module_spec.GetArchitecture();
- }
+ // accurate.
+ update_platform_arch(matching_module_spec.GetArchitecture());
} else {
StreamString platform_arch_strm;
StreamString module_arch_strm;
@@ -155,128 +155,119 @@ Status TargetList::CreateTargetInternal(
return error;
}
} else {
- // Only one arch and none was specified
+ // Only one arch and none was specified.
prefer_platform_arch = true;
platform_arch = matching_module_spec.GetArchitecture();
}
}
+ } else if (arch.IsValid()) {
+ // Fat binary. A (valid) architecture was specified.
+ module_spec.GetArchitecture() = arch;
+ if (module_specs.FindMatchingModuleSpec(module_spec,
+ matching_module_spec))
+ update_platform_arch(matching_module_spec.GetArchitecture());
} else {
- if (arch.IsValid()) {
- module_spec.GetArchitecture() = arch;
- if (module_specs.FindMatchingModuleSpec(module_spec,
- matching_module_spec)) {
- prefer_platform_arch = true;
- platform_arch = matching_module_spec.GetArchitecture();
- }
- } else {
- // No architecture specified, check if there is only one platform for
- // all of the architectures.
-
- typedef std::vector<PlatformSP> PlatformList;
- PlatformList platforms;
- PlatformSP host_platform_sp = Platform::GetHostPlatform();
- for (size_t i = 0; i < num_specs; ++i) {
- ModuleSpec module_spec;
- if (module_specs.GetModuleSpecAtIndex(i, module_spec)) {
- // See if there was a selected platform and check that first
- // since the user may have specified it.
- if (platform_sp) {
- if (platform_sp->IsCompatibleArchitecture(
- module_spec.GetArchitecture(), false, nullptr)) {
- platforms.push_back(platform_sp);
- continue;
- }
- }
-
- // Next check the host platform it if wasn't already checked
- // above
- if (host_platform_sp &&
- (!platform_sp ||
- host_platform_sp->GetName() != platform_sp->GetName())) {
- if (host_platform_sp->IsCompatibleArchitecture(
- module_spec.GetArchitecture(), false, nullptr)) {
- platforms.push_back(host_platform_sp);
- continue;
- }
+ // Fat binary. No architecture specified, check if there is
+ // only one platform for all of the architectures.
+ PlatformSP host_platform_sp = Platform::GetHostPlatform();
+ std::vector<PlatformSP> platforms;
+ for (size_t i = 0; i < num_specs; ++i) {
+ ModuleSpec module_spec;
+ if (module_specs.GetModuleSpecAtIndex(i, module_spec)) {
+ // First consider the platform specified by the user, if any, and
+ // the selected platform otherwise.
+ if (platform_sp) {
+ if (platform_sp->IsCompatibleArchitecture(
+ module_spec.GetArchitecture(), false, nullptr)) {
+ platforms.push_back(platform_sp);
+ continue;
}
+ }
- // Just find a platform that matches the architecture in the
- // executable file
- PlatformSP fallback_platform_sp(
- Platform::GetPlatformForArchitecture(
- module_spec.GetArchitecture(), nullptr));
- if (fallback_platform_sp) {
- platforms.push_back(fallback_platform_sp);
+ // Now consider the host platform if it is different from the
+ // specified/selected platform.
+ if (host_platform_sp &&
+ (!platform_sp ||
+ host_platform_sp->GetName() != platform_sp->GetName())) {
+ if (host_platform_sp->IsCompatibleArchitecture(
+ module_spec.GetArchitecture(), false, nullptr)) {
+ platforms.push_back(host_platform_sp);
+ continue;
}
}
- }
- Platform *platform_ptr = nullptr;
- bool more_than_one_platforms = false;
- for (const auto &the_platform_sp : platforms) {
- if (platform_ptr) {
- if (platform_ptr->GetName() != the_platform_sp->GetName()) {
- more_than_one_platforms = true;
- platform_ptr = nullptr;
- break;
- }
- } else {
- platform_ptr = the_platform_sp.get();
+ // Finally find a platform that matches the architecture in the
+ // executable file.
+ PlatformSP fallback_platform_sp(
+ Platform::GetPlatformForArchitecture(
+ module_spec.GetArchitecture(), nullptr));
+ if (fallback_platform_sp) {
+ platforms.push_back(fallback_platform_sp);
}
}
+ }
+ Platform *platform_ptr = nullptr;
+ bool more_than_one_platforms = false;
+ for (const auto &the_platform_sp : platforms) {
if (platform_ptr) {
- // All platforms for all modules in the executable match, so we can
- // select this platform
- platform_sp = platforms.front();
- } else if (!more_than_one_platforms) {
- // No platforms claim to support this file
- error.SetErrorString("No matching platforms found for this file, "
- "specify one with the --platform option");
- return error;
+ if (platform_ptr->GetName() != the_platform_sp->GetName()) {
+ more_than_one_platforms = true;
+ platform_ptr = nullptr;
+ break;
+ }
} else {
- // More than one platform claims to support this file, so the
- // --platform option must be specified
- StreamString error_strm;
- std::set<Platform *> platform_set;
- error_strm.Printf(
- "more than one platform supports this executable (");
- for (const auto &the_platform_sp : platforms) {
- if (platform_set.find(the_platform_sp.get()) ==
- platform_set.end()) {
- if (!platform_set.empty())
- error_strm.PutCString(", ");
- error_strm.PutCString(the_platform_sp->GetName().GetCString());
- platform_set.insert(the_platform_sp.get());
- }
+ platform_ptr = the_platform_sp.get();
+ }
+ }
+
+ if (platform_ptr) {
+ // All platforms for all modules in the executable match, so we can
+ // select this platform.
+ platform_sp = platforms.front();
+ } else if (!more_than_one_platforms) {
+ // No platforms claim to support this file.
+ error.SetErrorString("no matching platforms found for this file");
+ return error;
+ } else {
+ // More than one platform claims to support this file.
+ StreamString error_strm;
+ std::set<Platform *> platform_set;
+ error_strm.Printf(
+ "more than one platform supports this executable (");
+ for (const auto &the_platform_sp : platforms) {
+ if (platform_set.find(the_platform_sp.get()) ==
+ platform_set.end()) {
+ if (!platform_set.empty())
+ error_strm.PutCString(", ");
+ error_strm.PutCString(the_platform_sp->GetName().GetCString());
+ platform_set.insert(the_platform_sp.get());
}
- error_strm.Printf(
- "), use the --platform option to specify a platform");
- error.SetErrorString(error_strm.GetString());
- return error;
}
+ error_strm.Printf("), specify an architecture to disambiguate");
+ error.SetErrorString(error_strm.GetString());
+ return error;
}
}
}
}
// If we have a valid architecture, make sure the current platform is
- // compatible with that architecture
+ // compatible with that architecture.
if (!prefer_platform_arch && arch.IsValid()) {
- if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) {
+ if (!platform_sp->IsCompatibleArchitecture(arch, false, nullptr)) {
platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
- if (!is_dummy_target && platform_sp)
+ if (platform_sp)
debugger.GetPlatformList().SetSelectedPlatform(platform_sp);
}
} else if (platform_arch.IsValid()) {
- // if "arch" isn't valid, yet "platform_arch" is, it means we have an
- // executable file with a single architecture which should be used
+ // If "arch" isn't valid, yet "platform_arch" is, it means we have an
+ // executable file with a single architecture which should be used.
ArchSpec fixed_platform_arch;
- if (!platform_sp->IsCompatibleArchitecture(platform_arch, false,
- &fixed_platform_arch)) {
+ if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, nullptr)) {
platform_sp = Platform::GetPlatformForArchitecture(platform_arch,
&fixed_platform_arch);
- if (!is_dummy_target && platform_sp)
+ if (platform_sp)
debugger.GetPlatformList().SetSelectedPlatform(platform_sp);
}
}
@@ -284,32 +275,9 @@ Status TargetList::CreateTargetInternal(
if (!platform_arch.IsValid())
platform_arch = arch;
- error = TargetList::CreateTargetInternal(
- debugger, user_exe_path, platform_arch, load_dependent_files, platform_sp,
- target_sp, is_dummy_target);
- return error;
-}
-
-lldb::TargetSP TargetList::GetDummyTarget(lldb_private::Debugger &debugger) {
- // FIXME: Maybe the dummy target should be per-Debugger
- if (!m_dummy_target_sp || !m_dummy_target_sp->IsValid()) {
- ArchSpec arch(Target::GetDefaultArchitecture());
- if (!arch.IsValid())
- arch = HostInfo::GetArchitecture();
- Status err = CreateDummyTarget(
- debugger, arch.GetTriple().getTriple().c_str(), m_dummy_target_sp);
- }
-
- return m_dummy_target_sp;
-}
-
-Status TargetList::CreateDummyTarget(Debugger &debugger,
- llvm::StringRef specified_arch_name,
- lldb::TargetSP &target_sp) {
- PlatformSP host_platform_sp(Platform::GetHostPlatform());
- return CreateTargetInternal(
- debugger, (const char *)nullptr, specified_arch_name, eLoadDependentsNo,
- (const OptionGroupPlatform *)nullptr, target_sp, true);
+ return TargetList::CreateTargetInternal(debugger, user_exe_path,
+ platform_arch, load_dependent_files,
+ platform_sp, target_sp);
}
Status TargetList::CreateTargetInternal(Debugger &debugger,
@@ -317,13 +285,12 @@ Status TargetList::CreateTargetInternal(Debugger &debugger,
const ArchSpec &specified_arch,
LoadDependentFiles load_dependent_files,
lldb::PlatformSP &platform_sp,
- lldb::TargetSP &target_sp,
- bool is_dummy_target) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat, "TargetList::CreateTarget (file = '%s', arch = '%s')",
- user_exe_path.str().c_str(), specified_arch.GetArchitectureName());
+ lldb::TargetSP &target_sp) {
+ LLDB_SCOPED_TIMERF("TargetList::CreateTarget (file = '%s', arch = '%s')",
+ user_exe_path.str().c_str(),
+ specified_arch.GetArchitectureName());
Status error;
+ const bool is_dummy_target = false;
ArchSpec arch(specified_arch);
@@ -407,117 +374,106 @@ Status TargetList::CreateTargetInternal(Debugger &debugger,
target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target));
}
- if (target_sp) {
- // Set argv0 with what the user typed, unless the user specified a
- // directory. If the user specified a directory, then it is probably a
- // bundle that was resolved and we need to use the resolved bundle path
- if (!user_exe_path.empty()) {
- // Use exactly what the user typed as the first argument when we exec or
- // posix_spawn
- if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) {
- target_sp->SetArg0(resolved_bundle_exe_path);
- } else {
- // Use resolved path
- target_sp->SetArg0(file.GetPath().c_str());
- }
- }
- if (file.GetDirectory()) {
- FileSpec file_dir;
- file_dir.GetDirectory() = file.GetDirectory();
- target_sp->AppendExecutableSearchPaths(file_dir);
- }
+ if (!target_sp)
+ return error;
- // Don't put the dummy target in the target list, it's held separately.
- if (!is_dummy_target) {
- 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:
- target_sp->PrimeFromDummyTarget(debugger.GetDummyTarget());
+ // Set argv0 with what the user typed, unless the user specified a
+ // directory. If the user specified a directory, then it is probably a
+ // bundle that was resolved and we need to use the resolved bundle path
+ if (!user_exe_path.empty()) {
+ // Use exactly what the user typed as the first argument when we exec or
+ // posix_spawn
+ if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) {
+ target_sp->SetArg0(resolved_bundle_exe_path);
} else {
- m_dummy_target_sp = target_sp;
+ // Use resolved path
+ target_sp->SetArg0(file.GetPath().c_str());
}
}
+ if (file.GetDirectory()) {
+ FileSpec file_dir;
+ file_dir.GetDirectory() = file.GetDirectory();
+ target_sp->AppendExecutableSearchPaths(file_dir);
+ }
+
+ // Now prime this from the dummy target:
+ target_sp->PrimeFromDummyTarget(debugger.GetDummyTarget());
return error;
}
bool TargetList::DeleteTarget(TargetSP &target_sp) {
std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
- collection::iterator pos, end = m_target_list.end();
+ auto it = std::find(m_target_list.begin(), m_target_list.end(), target_sp);
+ if (it == m_target_list.end())
+ return false;
- for (pos = m_target_list.begin(); pos != end; ++pos) {
- if (pos->get() == target_sp.get()) {
- m_target_list.erase(pos);
- return true;
- }
- }
- return false;
+ m_target_list.erase(it);
+ return true;
}
TargetSP TargetList::FindTargetWithExecutableAndArchitecture(
const FileSpec &exe_file_spec, const ArchSpec *exe_arch_ptr) const {
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) {
- Module *exe_module = (*pos)->GetExecutableModulePointer();
-
- if (exe_module) {
- if (FileSpec::Match(exe_file_spec, exe_module->GetFileSpec())) {
- if (exe_arch_ptr) {
- if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture()))
- continue;
- }
- target_sp = *pos;
- break;
- }
- }
- }
- return target_sp;
+ auto it = std::find_if(m_target_list.begin(), m_target_list.end(),
+ [&exe_file_spec, exe_arch_ptr](const TargetSP &item) {
+ Module *exe_module = item->GetExecutableModulePointer();
+ if (!exe_module ||
+ !FileSpec::Match(exe_file_spec, exe_module->GetFileSpec()))
+ return false;
+
+ return !exe_arch_ptr ||
+ exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture());
+ });
+
+ if (it != m_target_list.end())
+ return *it;
+
+ return TargetSP();
}
TargetSP TargetList::FindTargetWithProcessID(lldb::pid_t pid) const {
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) {
- Process *process = (*pos)->GetProcessSP().get();
- if (process && process->GetID() == pid) {
- target_sp = *pos;
- break;
- }
- }
- return target_sp;
+ auto it = std::find_if(m_target_list.begin(), m_target_list.end(),
+ [pid](const TargetSP &item) {
+ auto *process_ptr = item->GetProcessSP().get();
+ return process_ptr && (process_ptr->GetID() == pid);
+ });
+
+ if (it != m_target_list.end())
+ return *it;
+
+ return TargetSP();
}
TargetSP TargetList::FindTargetWithProcess(Process *process) const {
TargetSP target_sp;
- if (process) {
- 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) {
- if (process == (*pos)->GetProcessSP().get()) {
- target_sp = *pos;
- break;
- }
- }
- }
+ if (!process)
+ return target_sp;
+
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
+ auto it = std::find_if(m_target_list.begin(), m_target_list.end(),
+ [process](const TargetSP &item) {
+ return item->GetProcessSP().get() == process;
+ });
+
+ if (it != m_target_list.end())
+ target_sp = *it;
+
return target_sp;
}
TargetSP TargetList::GetTargetSP(Target *target) const {
TargetSP target_sp;
- if (target) {
- 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) {
- if (target == (*pos).get()) {
- target_sp = *pos;
- break;
- }
- }
- }
+ if (!target)
+ return target_sp;
+
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
+ auto it = std::find_if(m_target_list.begin(), m_target_list.end(),
+ [target](const TargetSP &item) { return item.get() == target; });
+ if (it != m_target_list.end())
+ target_sp = *it;
+
return target_sp;
}
@@ -548,14 +504,11 @@ uint32_t TargetList::SignalIfRunning(lldb::pid_t pid, int signo) {
if (pid == LLDB_INVALID_PROCESS_ID) {
// Signal all processes with signal
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) {
- process = (*pos)->GetProcessSP().get();
- if (process) {
- if (process->IsAlive()) {
- ++num_signals_sent;
- process->Signal(signo);
- }
+ for (const auto &target_sp : m_target_list) {
+ process = target_sp->GetProcessSP().get();
+ if (process && process->IsAlive()) {
+ ++num_signals_sent;
+ process->Signal(signo);
}
}
} else {
@@ -563,11 +516,9 @@ uint32_t TargetList::SignalIfRunning(lldb::pid_t pid, int signo) {
TargetSP target_sp(FindTargetWithProcessID(pid));
if (target_sp) {
process = target_sp->GetProcessSP().get();
- if (process) {
- if (process->IsAlive()) {
- ++num_signals_sent;
- process->Signal(signo);
- }
+ if (process && process->IsAlive()) {
+ ++num_signals_sent;
+ process->Signal(signo);
}
}
}
@@ -589,26 +540,35 @@ lldb::TargetSP TargetList::GetTargetAtIndex(uint32_t idx) const {
uint32_t TargetList::GetIndexOfTarget(lldb::TargetSP target_sp) const {
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++) {
- if (target_sp == m_target_list[idx])
- return idx;
- }
+ auto it = std::find(m_target_list.begin(), m_target_list.end(), target_sp);
+ if (it != m_target_list.end())
+ return std::distance(m_target_list.begin(), it);
return UINT32_MAX;
}
-uint32_t TargetList::SetSelectedTarget(Target *target) {
+void TargetList::AddTargetInternal(TargetSP target_sp, bool do_select) {
+ lldbassert(std::find(m_target_list.begin(), m_target_list.end(), target_sp) ==
+ m_target_list.end() &&
+ "target already exists it the list");
+ m_target_list.push_back(std::move(target_sp));
+ if (do_select)
+ SetSelectedTargetInternal(m_target_list.size() - 1);
+}
+
+void TargetList::SetSelectedTargetInternal(uint32_t index) {
+ lldbassert(!m_target_list.empty());
+ m_selected_target_idx = index < m_target_list.size() ? index : 0;
+}
+
+void TargetList::SetSelectedTarget(uint32_t index) {
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();
- for (pos = begin; pos != end; ++pos) {
- if (pos->get() == target) {
- m_selected_target_idx = std::distance(begin, pos);
- return m_selected_target_idx;
- }
- }
- m_selected_target_idx = 0;
- return m_selected_target_idx;
+ SetSelectedTargetInternal(index);
+}
+
+void TargetList::SetSelectedTarget(const TargetSP &target_sp) {
+ std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
+ auto it = std::find(m_target_list.begin(), m_target_list.end(), target_sp);
+ SetSelectedTargetInternal(std::distance(m_target_list.begin(), it));
}
lldb::TargetSP TargetList::GetSelectedTarget() {
diff --git a/contrib/llvm-project/lldb/source/Target/TargetProperties.td b/contrib/llvm-project/lldb/source/Target/TargetProperties.td
index ae3abe354856..2d6a4358082a 100644
--- a/contrib/llvm-project/lldb/source/Target/TargetProperties.td
+++ b/contrib/llvm-project/lldb/source/Target/TargetProperties.td
@@ -20,6 +20,10 @@ let Definition = "target" in {
def ExprPrefix: Property<"expr-prefix", "FileSpec">,
DefaultStringValue<"">,
Desc<"Path to a file containing expressions to be prepended to all expressions.">;
+ def ExprErrorLimit: Property<"expr-error-limit", "UInt64">,
+ DefaultUnsignedValue<5>,
+ Desc<"The maximum amount of errors to emit while parsing an expression. "
+ "A value of 0 means to always continue parsing if possible.">;
def PreferDynamic: Property<"prefer-dynamic-value", "Enum">,
DefaultEnumValue<"eDynamicDontRunTarget">,
EnumValues<"OptionEnumValues(g_dynamic_value_types)">,
@@ -32,7 +36,7 @@ let Definition = "target" in {
Desc<"Skip function prologues when setting breakpoints by name.">;
def SourceMap: Property<"source-map", "PathMap">,
DefaultStringValue<"">,
- Desc<"Source path remappings are used to track the change of location between a source file when built, and where it exists on the current system. It consists of an array of duples, the first element of each duple is some part (starting at the root) of the path to the file when it was built, and the second is where the remainder of the original build hierarchy is rooted on the local system. Each element of the array is checked in order and the first one that results in a match wins.">;
+ Desc<"Source path remappings apply substitutions to the paths of source files, typically needed to debug from a different host than the one that built the target. The source-map property consists of an array of pairs, the first element is a path prefix, and the second is its replacement. The syntax is `prefix1 replacement1 prefix2 replacement2...`. The pairs are checked in order, the first prefix that matches is used, and that prefix is substituted with the replacement. A common pattern is to use source-map in conjunction with the clang -fdebug-prefix-map flag. In the build, use `-fdebug-prefix-map=/path/to/build_dir=.` to rewrite the host specific build directory to `.`. Then for debugging, use `settings set target.source-map . /path/to/local_dir` to convert `.` to a valid local path.">;
def ExecutableSearchPaths: Property<"exec-search-paths", "FileSpecList">,
DefaultStringValue<"">,
Desc<"Executable search paths to use when locating executable files whose paths don't match the local file system.">;
@@ -45,9 +49,11 @@ let Definition = "target" in {
def AutoImportClangModules: Property<"auto-import-clang-modules", "Boolean">,
DefaultTrue,
Desc<"Automatically load Clang modules referred to by the program.">;
- def ImportStdModule: Property<"import-std-module", "Boolean">,
- DefaultFalse,
- Desc<"Import the C++ std module to improve debugging STL containers.">;
+ def ImportStdModule: Property<"import-std-module", "Enum">,
+ DefaultEnumValue<"eImportStdModuleFalse">,
+ EnumValues<"OptionEnumValues(g_import_std_module_value_types)">,
+ Desc<"Import the 'std' C++ module to improve expression parsing involving "
+ " C++ standard library types.">;
def AutoApplyFixIts: Property<"auto-apply-fixits", "Boolean">,
DefaultTrue,
Desc<"Automatically apply fix-it hints to expressions.">;
@@ -111,6 +117,9 @@ let Definition = "target" in {
def DisableSTDIO: Property<"disable-stdio", "Boolean">,
DefaultFalse,
Desc<"Disable stdin/stdout for process (e.g. for a GUI application)">;
+ def InheritTCC: Property<"inherit-tcc", "Boolean">,
+ DefaultFalse,
+ Desc<"Inherit the TCC permissions from the inferior's parent instead of making the process itself responsible.">;
def InlineStrategy: Property<"inline-breakpoint-strategy", "Enum">,
DefaultEnumValue<"eInlineBreakpointsAlways">,
EnumValues<"OptionEnumValues(g_inline_breakpoint_enums)">,
@@ -214,6 +223,9 @@ let Definition = "process" in {
def UtilityExpressionTimeout: Property<"utility-expression-timeout", "UInt64">,
DefaultUnsignedValue<15>,
Desc<"The time in seconds to wait for LLDB-internal utility expressions.">;
+ def SteppingRunsAllThreads: Property<"run-all-threads", "Boolean">,
+ DefaultFalse,
+ Desc<"If true, stepping operations will run all threads. This is equivalent to setting the run-mode option to 'all-threads'.">;
}
let Definition = "platform" in {
diff --git a/contrib/llvm-project/lldb/source/Target/Thread.cpp b/contrib/llvm-project/lldb/source/Target/Thread.cpp
index 24cf4bf3ee1e..049e458d8b19 100644
--- a/contrib/llvm-project/lldb/source/Target/Thread.cpp
+++ b/contrib/llvm-project/lldb/source/Target/Thread.cpp
@@ -1103,6 +1103,22 @@ void Thread::DiscardPlan() {
discarded_plan_sp->GetThread().GetID());
}
+void Thread::AutoCompleteThreadPlans(CompletionRequest &request) const {
+ const ThreadPlanStack &plans = GetPlans();
+ if (!plans.AnyPlans())
+ return;
+
+ // Iterate from the second plan (index: 1) to skip the base plan.
+ ThreadPlanSP p;
+ uint32_t i = 1;
+ while ((p = plans.GetPlanByIndex(i, false))) {
+ StreamString strm;
+ p->GetDescription(&strm, eDescriptionLevelInitial);
+ request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
+ i++;
+ }
+}
+
ThreadPlan *Thread::GetCurrentPlan() const {
return GetPlans().GetCurrentPlan().get();
}
@@ -1380,7 +1396,7 @@ lldb::ThreadPlanSP Thread::QueueThreadPlanForStepScripted(
ThreadPlanSP thread_plan_sp(new ThreadPlanPython(*this, class_name,
extra_args_impl));
-
+ thread_plan_sp->SetStopOthers(stop_other_threads);
status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
return thread_plan_sp;
}
@@ -1661,7 +1677,7 @@ Thread::GetStackFrameSPForStackFramePtr(StackFrame *stack_frame_ptr) {
return GetStackFrameList()->GetStackFrameSPForStackFramePtr(stack_frame_ptr);
}
-const char *Thread::StopReasonAsCString(lldb::StopReason reason) {
+std::string Thread::StopReasonAsString(lldb::StopReason reason) {
switch (reason) {
case eStopReasonInvalid:
return "invalid";
@@ -1687,13 +1703,10 @@ const char *Thread::StopReasonAsCString(lldb::StopReason reason) {
return "instrumentation break";
}
- static char unknown_state_string[64];
- snprintf(unknown_state_string, sizeof(unknown_state_string),
- "StopReason = %i", reason);
- return unknown_state_string;
+ return "StopReason = " + std::to_string(reason);
}
-const char *Thread::RunModeAsCString(lldb::RunMode mode) {
+std::string Thread::RunModeAsString(lldb::RunMode mode) {
switch (mode) {
case eOnlyThisThread:
return "only this thread";
@@ -1703,10 +1716,7 @@ const char *Thread::RunModeAsCString(lldb::RunMode mode) {
return "only during stepping";
}
- static char unknown_state_string[64];
- snprintf(unknown_state_string, sizeof(unknown_state_string), "RunMode = %i",
- mode);
- return unknown_state_string;
+ return "RunMode = " + std::to_string(mode);
}
size_t Thread::GetStatus(Stream &strm, uint32_t start_frame,
diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp
index d8e92b8fd0de..c7a00e2450c8 100644
--- a/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp
+++ b/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp
@@ -99,6 +99,8 @@ Vote ThreadPlan::ShouldReportRun(Event *event_ptr) {
return m_run_vote;
}
+void ThreadPlan::ClearThreadCache() { m_thread = nullptr; }
+
bool ThreadPlan::StopOthers() {
ThreadPlan *prev_plan;
prev_plan = GetPreviousPlan();
@@ -134,7 +136,7 @@ bool ThreadPlan::WillResume(StateType resume_state, bool current_plan) {
}
}
bool success = DoWillResume(resume_state, current_plan);
- m_thread = nullptr; // We don't cache the thread pointer over resumes. This
+ ClearThreadCache(); // We don't cache the thread pointer over resumes. This
// Thread might go away, and another Thread represent
// the same underlying object on a later stop.
return success;
diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp
index dbe26f42c9bf..f525173f8a51 100644
--- a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp
+++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp
@@ -260,9 +260,9 @@ bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
stop_reason = eStopReasonNone;
else
stop_reason = m_real_stop_info_sp->GetStopReason();
- LLDB_LOGF(log,
- "ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.",
- Thread::StopReasonAsCString(stop_reason));
+ LLDB_LOG(log,
+ "ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - {0}.",
+ Thread::StopReasonAsString(stop_reason));
if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
return true;
diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp
index 8171186319f5..e83f0e9e715e 100644
--- a/contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp
+++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp
@@ -25,11 +25,12 @@ using namespace lldb_private;
// ThreadPlanPython
-ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name,
+ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name,
StructuredDataImpl *args_data)
: ThreadPlan(ThreadPlan::eKindPython, "Python based Thread Plan", thread,
eVoteNoOpinion, eVoteNoOpinion),
- m_class_name(class_name), m_args_data(args_data), m_did_push(false) {
+ m_class_name(class_name), m_args_data(args_data), m_did_push(false),
+ m_stop_others(false) {
SetIsMasterPlan(true);
SetOkayToDiscard(true);
SetPrivate(false);
@@ -162,13 +163,6 @@ lldb::StateType ThreadPlanPython::GetPlanRunState() {
}
// The ones below are not currently exported to Python.
-
-bool ThreadPlanPython::StopOthers() {
- // For now Python plans run all threads, but we should add some controls for
- // this.
- return false;
-}
-
void ThreadPlanPython::GetDescription(Stream *s, lldb::DescriptionLevel level) {
s->Printf("Python thread plan implemented by class %s.",
m_class_name.c_str());
diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp
index 1cfc41dcd390..ad37669c31fd 100644
--- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp
+++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp
@@ -369,24 +369,16 @@ ThreadPlan *ThreadPlanStack::GetInnermostExpression() const {
return nullptr;
}
+void ThreadPlanStack::ClearThreadCache() {
+ for (lldb::ThreadPlanSP thread_plan_sp : m_plans)
+ thread_plan_sp->ClearThreadCache();
+}
+
void ThreadPlanStack::WillResume() {
m_completed_plans.clear();
m_discarded_plans.clear();
}
-const ThreadPlanStack::PlanStack &
-ThreadPlanStack::GetStackOfKind(ThreadPlanStack::StackKind kind) const {
- switch (kind) {
- case ePlans:
- return m_plans;
- case eCompletedPlans:
- return m_completed_plans;
- case eDiscardedPlans:
- return m_discarded_plans;
- }
- llvm_unreachable("Invalid StackKind value");
-}
-
void ThreadPlanStackMap::Update(ThreadList &current_threads,
bool delete_missing,
bool check_for_new) {
diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInRange.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInRange.cpp
index c5f81d6665a1..a03bd93ac638 100644
--- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInRange.cpp
+++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepInRange.cpp
@@ -47,22 +47,6 @@ ThreadPlanStepInRange::ThreadPlanStepInRange(
step_out_avoids_code_without_debug_info);
}
-ThreadPlanStepInRange::ThreadPlanStepInRange(
- Thread &thread, const AddressRange &range,
- const SymbolContext &addr_context, const char *step_into_target,
- lldb::RunMode stop_others, LazyBool step_in_avoids_code_without_debug_info,
- LazyBool step_out_avoids_code_without_debug_info)
- : ThreadPlanStepRange(ThreadPlan::eKindStepInRange,
- "Step Range stepping in", thread, range, addr_context,
- stop_others),
- ThreadPlanShouldStopHere(this), m_step_past_prologue(true),
- m_virtual_step(false), m_step_into_target(step_into_target) {
- SetCallbacks();
- SetFlagsToDefault();
- SetupAvoidNoDebug(step_in_avoids_code_without_debug_info,
- step_out_avoids_code_without_debug_info);
-}
-
ThreadPlanStepInRange::~ThreadPlanStepInRange() = default;
void ThreadPlanStepInRange::SetupAvoidNoDebug(
diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp
index f3d35a91fcbc..f188d827faae 100644
--- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp
+++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp
@@ -62,8 +62,8 @@ bool ThreadPlanStepOverBreakpoint::DoPlanExplainsStop(Event *event_ptr) {
StopReason reason = stop_info_sp->GetStopReason();
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
- LLDB_LOGF(log, "Step over breakpoint stopped for reason: %s.",
- Thread::StopReasonAsCString(reason));
+ LLDB_LOG(log, "Step over breakpoint stopped for reason: {0}.",
+ Thread::StopReasonAsString(reason));
switch (reason) {
case eStopReasonTrace:
diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepRange.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepRange.cpp
index f4b2ee3d08a2..3c42cd750dad 100644
--- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepRange.cpp
+++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepRange.cpp
@@ -327,13 +327,9 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() {
if (instructions == nullptr)
return false;
else {
- Target &target = GetThread().GetProcess()->GetTarget();
const bool ignore_calls = GetKind() == eKindStepOverRange;
- uint32_t branch_index =
- instructions->GetIndexOfNextBranchInstruction(pc_index, target,
- ignore_calls,
- &m_found_calls);
-
+ uint32_t branch_index = instructions->GetIndexOfNextBranchInstruction(
+ pc_index, ignore_calls, &m_found_calls);
Address run_to_address;
// If we didn't find a branch, run to the end of the range.
diff --git a/contrib/llvm-project/lldb/source/Target/ThreadTrace.cpp b/contrib/llvm-project/lldb/source/Target/ThreadTrace.cpp
new file mode 100644
index 000000000000..346f36a737d7
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Target/ThreadTrace.cpp
@@ -0,0 +1,39 @@
+//===-- ThreadTrace.cpp ---------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ThreadTrace.h"
+
+#include <memory>
+
+#include "Plugins/Process/Utility/RegisterContextHistory.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void ThreadTrace::RefreshStateAfterStop() {}
+
+RegisterContextSP ThreadTrace::GetRegisterContext() {
+ if (!m_reg_context_sp)
+ m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
+
+ return m_reg_context_sp;
+}
+
+RegisterContextSP
+ThreadTrace::CreateRegisterContextForFrame(StackFrame *frame) {
+ // Eventually this will calculate the register context based on the current
+ // trace position.
+ return std::make_shared<RegisterContextHistory>(
+ *this, 0, GetProcess()->GetAddressByteSize(), LLDB_INVALID_ADDRESS);
+}
+
+bool ThreadTrace::CalculateStopInfo() { return false; }
+
+const FileSpec &ThreadTrace::GetTraceFile() const { return m_trace_file; }
diff --git a/contrib/llvm-project/lldb/source/Target/Trace.cpp b/contrib/llvm-project/lldb/source/Target/Trace.cpp
new file mode 100644
index 000000000000..d19115b2d1f9
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Target/Trace.cpp
@@ -0,0 +1,268 @@
+//===-- Trace.cpp ---------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/Trace.h"
+
+#include "llvm/Support/Format.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/SectionLoadList.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/Stream.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm;
+
+// Helper structs used to extract the type of a trace session json without
+// having to parse the entire object.
+
+struct JSONSimplePluginSettings {
+ std::string type;
+};
+
+struct JSONSimpleTraceSession {
+ JSONSimplePluginSettings trace;
+};
+
+namespace llvm {
+namespace json {
+
+bool fromJSON(const Value &value, JSONSimplePluginSettings &plugin_settings,
+ Path path) {
+ json::ObjectMapper o(value, path);
+ return o && o.map("type", plugin_settings.type);
+}
+
+bool fromJSON(const Value &value, JSONSimpleTraceSession &session, Path path) {
+ json::ObjectMapper o(value, path);
+ return o && o.map("trace", session.trace);
+}
+
+} // namespace json
+} // namespace llvm
+
+static Error createInvalidPlugInError(StringRef plugin_name) {
+ return createStringError(
+ std::errc::invalid_argument,
+ "no trace plug-in matches the specified type: \"%s\"",
+ plugin_name.data());
+}
+
+Expected<lldb::TraceSP> Trace::FindPlugin(Debugger &debugger,
+ const json::Value &trace_session_file,
+ StringRef session_file_dir) {
+ JSONSimpleTraceSession json_session;
+ json::Path::Root root("traceSession");
+ if (!json::fromJSON(trace_session_file, json_session, root))
+ return root.getError();
+
+ ConstString plugin_name(json_session.trace.type);
+ if (auto create_callback = PluginManager::GetTraceCreateCallback(plugin_name))
+ return create_callback(trace_session_file, session_file_dir, debugger);
+
+ return createInvalidPlugInError(json_session.trace.type);
+}
+
+Expected<StringRef> Trace::FindPluginSchema(StringRef name) {
+ ConstString plugin_name(name);
+ StringRef schema = PluginManager::GetTraceSchema(plugin_name);
+ if (!schema.empty())
+ return schema;
+
+ return createInvalidPlugInError(name);
+}
+
+static int GetNumberOfDigits(size_t num) {
+ return num == 0 ? 1 : static_cast<int>(log10(num)) + 1;
+}
+
+/// Dump the symbol context of the given instruction address if it's different
+/// from the symbol context of the previous instruction in the trace.
+///
+/// \param[in] prev_sc
+/// The symbol context of the previous instruction in the trace.
+///
+/// \param[in] address
+/// The address whose symbol information will be dumped.
+///
+/// \return
+/// The symbol context of the current address, which might differ from the
+/// previous one.
+static SymbolContext DumpSymbolContext(Stream &s, const SymbolContext &prev_sc,
+ Target &target, const Address &address) {
+ AddressRange range;
+ if (prev_sc.GetAddressRange(eSymbolContextEverything, 0,
+ /*inline_block_range*/ false, range) &&
+ range.ContainsFileAddress(address))
+ return prev_sc;
+
+ SymbolContext sc;
+ address.CalculateSymbolContext(&sc, eSymbolContextEverything);
+
+ if (!prev_sc.module_sp && !sc.module_sp)
+ return sc;
+ if (prev_sc.module_sp == sc.module_sp && !sc.function && !sc.symbol &&
+ !prev_sc.function && !prev_sc.symbol)
+ return sc;
+
+ s.Printf(" ");
+
+ if (!sc.module_sp)
+ s.Printf("(none)");
+ else if (!sc.function && !sc.symbol)
+ s.Printf("%s`(none)",
+ sc.module_sp->GetFileSpec().GetFilename().AsCString());
+ else
+ sc.DumpStopContext(&s, &target, address, /*show_fullpath*/ false,
+ /*show_module*/ true, /*show_inlined_frames*/ false,
+ /*show_function_arguments*/ true,
+ /*show_function_name*/ true,
+ /*show_inline_callsite_line_info*/ false);
+ s.Printf("\n");
+ return sc;
+}
+
+/// Dump an instruction given by its address using a given disassembler, unless
+/// the instruction is not present in the disassembler.
+///
+/// \param[in] disassembler
+/// A disassembler containing a certain instruction list.
+///
+/// \param[in] address
+/// The address of the instruction to dump.
+///
+/// \return
+/// \b true if the information could be dumped, \b false otherwise.
+static bool TryDumpInstructionInfo(Stream &s,
+ const DisassemblerSP &disassembler,
+ const ExecutionContext &exe_ctx,
+ const Address &address) {
+ if (!disassembler)
+ return false;
+
+ if (InstructionSP instruction =
+ disassembler->GetInstructionList().GetInstructionAtAddress(address)) {
+ instruction->Dump(&s, /*show_address*/ false, /*show_bytes*/ false,
+ /*max_opcode_byte_size*/ 0, &exe_ctx,
+ /*sym_ctx*/ nullptr, /*prev_sym_ctx*/ nullptr,
+ /*disassembly_addr_format*/ nullptr,
+ /*max_address_text_size*/ 0);
+ return true;
+ }
+
+ return false;
+}
+
+/// Dump an instruction instruction given by its address.
+///
+/// \param[in] prev_disassembler
+/// The disassembler that was used to dump the previous instruction in the
+/// trace. It is useful to avoid recomputations.
+///
+/// \param[in] address
+/// The address of the instruction to dump.
+///
+/// \return
+/// A disassembler that contains the given instruction, which might differ
+/// from the previous disassembler.
+static DisassemblerSP
+DumpInstructionInfo(Stream &s, const SymbolContext &sc,
+ const DisassemblerSP &prev_disassembler,
+ ExecutionContext &exe_ctx, const Address &address) {
+ // We first try to use the previous disassembler
+ if (TryDumpInstructionInfo(s, prev_disassembler, exe_ctx, address))
+ return prev_disassembler;
+
+ // Now we try using the current function's disassembler
+ if (sc.function) {
+ DisassemblerSP disassembler =
+ sc.function->GetInstructions(exe_ctx, nullptr, true);
+ if (TryDumpInstructionInfo(s, disassembler, exe_ctx, address))
+ return disassembler;
+ }
+
+ // We fallback to disassembly one instruction
+ Target &target = exe_ctx.GetTargetRef();
+ const ArchSpec &arch = target.GetArchitecture();
+ AddressRange range(address, arch.GetMaximumOpcodeByteSize() * 1);
+ DisassemblerSP disassembler = Disassembler::DisassembleRange(
+ arch, /*plugin_name*/ nullptr,
+ /*flavor*/ nullptr, target, range, /*prefer_file_cache*/ true);
+ if (TryDumpInstructionInfo(s, disassembler, exe_ctx, address))
+ return disassembler;
+ return nullptr;
+}
+
+void Trace::DumpTraceInstructions(Thread &thread, Stream &s, size_t count,
+ size_t end_position, bool raw) {
+ size_t instructions_count = GetInstructionCount(thread);
+ s.Printf("thread #%u: tid = %" PRIu64 ", total instructions = %zu\n",
+ thread.GetIndexID(), thread.GetID(), instructions_count);
+
+ if (count == 0 || end_position >= instructions_count)
+ return;
+
+ size_t start_position =
+ end_position + 1 < count ? 0 : end_position + 1 - count;
+
+ int digits_count = GetNumberOfDigits(end_position);
+ auto printInstructionIndex = [&](size_t index) {
+ s.Printf(" [%*zu] ", digits_count, index);
+ };
+
+ bool was_prev_instruction_an_error = false;
+ Target &target = thread.GetProcess()->GetTarget();
+
+ SymbolContext sc;
+ DisassemblerSP disassembler;
+ ExecutionContext exe_ctx;
+ target.CalculateExecutionContext(exe_ctx);
+
+ TraverseInstructions(
+ thread, start_position, TraceDirection::Forwards,
+ [&](size_t index, Expected<lldb::addr_t> load_address) -> bool {
+ if (load_address) {
+ // We print an empty line after a sequence of errors to show more
+ // clearly that there's a gap in the trace
+ if (was_prev_instruction_an_error)
+ s.Printf(" ...missing instructions\n");
+
+ Address address;
+ if (!raw) {
+ target.GetSectionLoadList().ResolveLoadAddress(*load_address,
+ address);
+
+ sc = DumpSymbolContext(s, sc, target, address);
+ }
+
+ printInstructionIndex(index);
+ s.Printf("0x%016" PRIx64 " ", *load_address);
+
+ if (!raw) {
+ disassembler =
+ DumpInstructionInfo(s, sc, disassembler, exe_ctx, address);
+ }
+
+ was_prev_instruction_an_error = false;
+ } else {
+ printInstructionIndex(index);
+ s << toString(load_address.takeError());
+ was_prev_instruction_an_error = true;
+ if (!raw)
+ sc = SymbolContext();
+ }
+
+ s.Printf("\n");
+
+ return index < end_position;
+ });
+}
diff --git a/contrib/llvm-project/lldb/source/Target/TraceSessionFileParser.cpp b/contrib/llvm-project/lldb/source/Target/TraceSessionFileParser.cpp
new file mode 100644
index 000000000000..713fadc1eb4f
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Target/TraceSessionFileParser.cpp
@@ -0,0 +1,223 @@
+//===-- TraceSessionFileParser.cpp ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===/
+
+#include "lldb/Target/TraceSessionFileParser.h"
+
+#include <sstream>
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadTrace.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm;
+
+void TraceSessionFileParser::NormalizePath(lldb_private::FileSpec &file_spec) {
+ if (file_spec.IsRelative())
+ file_spec.PrependPathComponent(m_session_file_dir);
+}
+
+Error TraceSessionFileParser::ParseModule(lldb::TargetSP &target_sp,
+ const JSONModule &module) {
+ FileSpec system_file_spec(module.system_path);
+ NormalizePath(system_file_spec);
+
+ FileSpec local_file_spec(module.file.hasValue() ? *module.file
+ : module.system_path);
+ NormalizePath(local_file_spec);
+
+ ModuleSpec module_spec;
+ module_spec.GetFileSpec() = local_file_spec;
+ module_spec.GetPlatformFileSpec() = system_file_spec;
+
+ if (module.uuid.hasValue())
+ module_spec.GetUUID().SetFromStringRef(*module.uuid);
+
+ Status error;
+ ModuleSP module_sp =
+ target_sp->GetOrCreateModule(module_spec, /*notify*/ false, &error);
+
+ if (error.Fail())
+ return error.ToError();
+
+ bool load_addr_changed = false;
+ module_sp->SetLoadAddress(*target_sp, module.load_address.value, false,
+ load_addr_changed);
+ return llvm::Error::success();
+}
+
+Error TraceSessionFileParser::CreateJSONError(json::Path::Root &root,
+ const json::Value &value) {
+ std::string err;
+ raw_string_ostream os(err);
+ root.printErrorContext(value, os);
+ return createStringError(
+ std::errc::invalid_argument, "%s\n\nContext:\n%s\n\nSchema:\n%s",
+ toString(root.getError()).c_str(), os.str().c_str(), m_schema.data());
+}
+
+std::string TraceSessionFileParser::BuildSchema(StringRef plugin_schema) {
+ std::ostringstream schema_builder;
+ schema_builder << "{\n \"trace\": ";
+ schema_builder << plugin_schema.data() << ",";
+ schema_builder << R"(
+ "processes": [
+ {
+ "pid": integer,
+ "triple": string, // llvm-triple
+ "threads": [
+ {
+ "tid": integer,
+ "traceFile": string
+ }
+ ],
+ "modules": [
+ {
+ "systemPath": string, // original path of the module at runtime
+ "file"?: string, // copy of the file if not available at "systemPath"
+ "loadAddress": string, // string address in hex or decimal form
+ "uuid"?: string,
+ }
+ ]
+ }
+ ]
+ // Notes:
+ // All paths are either absolute or relative to the session file.
+}
+)";
+ return schema_builder.str();
+}
+
+ThreadTraceSP TraceSessionFileParser::ParseThread(ProcessSP &process_sp,
+ const JSONThread &thread) {
+ lldb::tid_t tid = static_cast<lldb::tid_t>(thread.tid);
+
+ FileSpec trace_file(thread.trace_file);
+ NormalizePath(trace_file);
+
+ ThreadTraceSP thread_sp =
+ std::make_shared<ThreadTrace>(*process_sp, tid, trace_file);
+ process_sp->GetThreadList().AddThread(thread_sp);
+ return thread_sp;
+}
+
+Expected<TraceSessionFileParser::ParsedProcess>
+TraceSessionFileParser::ParseProcess(const JSONProcess &process) {
+ TargetSP target_sp;
+ Status error = m_debugger.GetTargetList().CreateTarget(
+ m_debugger, /*user_exe_path*/ StringRef(), process.triple,
+ eLoadDependentsNo,
+ /*platform_options*/ nullptr, target_sp);
+
+ if (!target_sp)
+ return error.ToError();
+
+ ParsedProcess parsed_process;
+ parsed_process.target_sp = target_sp;
+
+ ProcessSP process_sp = target_sp->CreateProcess(
+ /*listener*/ nullptr, "trace",
+ /*crash_file*/ nullptr,
+ /*can_connect*/ false);
+
+ process_sp->SetID(static_cast<lldb::pid_t>(process.pid));
+
+ for (const JSONThread &thread : process.threads)
+ parsed_process.threads.push_back(ParseThread(process_sp, thread));
+
+ for (const JSONModule &module : process.modules)
+ if (Error err = ParseModule(target_sp, module))
+ return std::move(err);
+
+ if (!process.threads.empty())
+ process_sp->GetThreadList().SetSelectedThreadByIndexID(0);
+
+ // We invoke DidAttach to create a correct stopped state for the process and
+ // its threads.
+ ArchSpec process_arch;
+ process_sp->DidAttach(process_arch);
+
+ return parsed_process;
+}
+
+Expected<std::vector<TraceSessionFileParser::ParsedProcess>>
+TraceSessionFileParser::ParseCommonSessionFile(
+ const JSONTraceSessionBase &session) {
+ std::vector<ParsedProcess> parsed_processes;
+
+ auto onError = [&]() {
+ // Delete all targets that were created so far in case of failures
+ for (ParsedProcess &parsed_process : parsed_processes)
+ m_debugger.GetTargetList().DeleteTarget(parsed_process.target_sp);
+ };
+
+ for (const JSONProcess &process : session.processes) {
+ if (Expected<ParsedProcess> parsed_process = ParseProcess(process))
+ parsed_processes.push_back(std::move(*parsed_process));
+ else {
+ onError();
+ return parsed_process.takeError();
+ }
+ }
+ return parsed_processes;
+}
+
+namespace llvm {
+namespace json {
+
+bool fromJSON(const Value &value, TraceSessionFileParser::JSONAddress &address,
+ Path path) {
+ Optional<StringRef> s = value.getAsString();
+ if (s.hasValue() && !s->getAsInteger(0, address.value))
+ return true;
+
+ path.report("expected numeric string");
+ return false;
+}
+
+bool fromJSON(const Value &value, TraceSessionFileParser::JSONModule &module,
+ Path path) {
+ ObjectMapper o(value, path);
+ return o && o.map("systemPath", module.system_path) &&
+ o.map("file", module.file) &&
+ o.map("loadAddress", module.load_address) &&
+ o.map("uuid", module.uuid);
+}
+
+bool fromJSON(const Value &value, TraceSessionFileParser::JSONThread &thread,
+ Path path) {
+ ObjectMapper o(value, path);
+ return o && o.map("tid", thread.tid) && o.map("traceFile", thread.trace_file);
+}
+
+bool fromJSON(const Value &value, TraceSessionFileParser::JSONProcess &process,
+ Path path) {
+ ObjectMapper o(value, path);
+ return o && o.map("pid", process.pid) && o.map("triple", process.triple) &&
+ o.map("threads", process.threads) && o.map("modules", process.modules);
+}
+
+bool fromJSON(const Value &value,
+ TraceSessionFileParser::JSONTracePluginSettings &plugin_settings,
+ Path path) {
+ ObjectMapper o(value, path);
+ return o && o.map("type", plugin_settings.type);
+}
+
+bool fromJSON(const Value &value,
+ TraceSessionFileParser::JSONTraceSessionBase &session,
+ Path path) {
+ ObjectMapper o(value, path);
+ return o && o.map("processes", session.processes);
+}
+
+} // namespace json
+} // namespace llvm
diff --git a/contrib/llvm-project/lldb/source/Target/UnixSignals.cpp b/contrib/llvm-project/lldb/source/Target/UnixSignals.cpp
index dce32adbf0a3..4ec2e25c7e3b 100644
--- a/contrib/llvm-project/lldb/source/Target/UnixSignals.cpp
+++ b/contrib/llvm-project/lldb/source/Target/UnixSignals.cpp
@@ -65,55 +65,49 @@ UnixSignals::UnixSignals(const UnixSignals &rhs) : m_signals(rhs.m_signals) {}
UnixSignals::~UnixSignals() = default;
void UnixSignals::Reset() {
- // This builds one standard set of Unix Signals. If yours aren't quite in
+ // This builds one standard set of Unix Signals. If yours aren't quite in
// this order, you can either subclass this class, and use Add & Remove to
- // change them
- // or you can subclass and build them afresh in your constructor;
+ // change them or you can subclass and build them afresh in your constructor.
//
- // Note: the signals below are the Darwin signals. Do not change these!
+ // Note: the signals below are the Darwin signals. Do not change these!
+
m_signals.clear();
- // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION
- // ====== ============ ======== ====== ======
- // ===================================================
- AddSignal(1, "SIGHUP", false, true, true, "hangup");
- AddSignal(2, "SIGINT", true, true, true, "interrupt");
- AddSignal(3, "SIGQUIT", false, true, true, "quit");
- AddSignal(4, "SIGILL", false, true, true, "illegal instruction");
- AddSignal(5, "SIGTRAP", true, true, true,
- "trace trap (not reset when caught)");
- AddSignal(6, "SIGABRT", false, true, true, "abort()");
- AddSignal(7, "SIGEMT", false, true, true, "pollable event");
- AddSignal(8, "SIGFPE", false, true, true, "floating point exception");
- AddSignal(9, "SIGKILL", false, true, true, "kill");
- AddSignal(10, "SIGBUS", false, true, true, "bus error");
- AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation");
- AddSignal(12, "SIGSYS", false, true, true, "bad argument to system call");
- AddSignal(13, "SIGPIPE", false, false, false,
- "write on a pipe with no one to read it");
- AddSignal(14, "SIGALRM", false, false, false, "alarm clock");
- AddSignal(15, "SIGTERM", false, true, true,
- "software termination signal from kill");
- AddSignal(16, "SIGURG", false, false, false,
- "urgent condition on IO channel");
- AddSignal(17, "SIGSTOP", true, true, true,
- "sendable stop signal not from tty");
- AddSignal(18, "SIGTSTP", false, true, true, "stop signal from tty");
- AddSignal(19, "SIGCONT", false, true, true, "continue a stopped process");
- AddSignal(20, "SIGCHLD", false, false, false,
- "to parent on child stop or exit");
- AddSignal(21, "SIGTTIN", false, true, true,
- "to readers process group upon background tty read");
- AddSignal(22, "SIGTTOU", false, true, true,
- "to readers process group upon background tty write");
- AddSignal(23, "SIGIO", false, false, false, "input/output possible signal");
- AddSignal(24, "SIGXCPU", false, true, true, "exceeded CPU time limit");
- AddSignal(25, "SIGXFSZ", false, true, true, "exceeded file size limit");
- AddSignal(26, "SIGVTALRM", false, false, false, "virtual time alarm");
- AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm");
- AddSignal(28, "SIGWINCH", false, false, false, "window size changes");
- AddSignal(29, "SIGINFO", false, true, true, "information request");
- AddSignal(30, "SIGUSR1", false, true, true, "user defined signal 1");
- AddSignal(31, "SIGUSR2", false, true, true, "user defined signal 2");
+
+ // clang-format off
+ // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION
+ // ====== ============== ======== ====== ====== ===================================================
+ AddSignal(1, "SIGHUP", false, true, true, "hangup");
+ AddSignal(2, "SIGINT", true, true, true, "interrupt");
+ AddSignal(3, "SIGQUIT", false, true, true, "quit");
+ AddSignal(4, "SIGILL", false, true, true, "illegal instruction");
+ AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)");
+ AddSignal(6, "SIGABRT", false, true, true, "abort()");
+ AddSignal(7, "SIGEMT", false, true, true, "pollable event");
+ AddSignal(8, "SIGFPE", false, true, true, "floating point exception");
+ AddSignal(9, "SIGKILL", false, true, true, "kill");
+ AddSignal(10, "SIGBUS", false, true, true, "bus error");
+ AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation");
+ AddSignal(12, "SIGSYS", false, true, true, "bad argument to system call");
+ AddSignal(13, "SIGPIPE", false, false, false, "write on a pipe with no one to read it");
+ AddSignal(14, "SIGALRM", false, false, false, "alarm clock");
+ AddSignal(15, "SIGTERM", false, true, true, "software termination signal from kill");
+ AddSignal(16, "SIGURG", false, false, false, "urgent condition on IO channel");
+ AddSignal(17, "SIGSTOP", true, true, true, "sendable stop signal not from tty");
+ AddSignal(18, "SIGTSTP", false, true, true, "stop signal from tty");
+ AddSignal(19, "SIGCONT", false, false, true, "continue a stopped process");
+ AddSignal(20, "SIGCHLD", false, false, false, "to parent on child stop or exit");
+ AddSignal(21, "SIGTTIN", false, true, true, "to readers process group upon background tty read");
+ AddSignal(22, "SIGTTOU", false, true, true, "to readers process group upon background tty write");
+ AddSignal(23, "SIGIO", false, false, false, "input/output possible signal");
+ AddSignal(24, "SIGXCPU", false, true, true, "exceeded CPU time limit");
+ AddSignal(25, "SIGXFSZ", false, true, true, "exceeded file size limit");
+ AddSignal(26, "SIGVTALRM", false, false, false, "virtual time alarm");
+ AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm");
+ AddSignal(28, "SIGWINCH", false, false, false, "window size changes");
+ AddSignal(29, "SIGINFO", false, true, true, "information request");
+ AddSignal(30, "SIGUSR1", false, true, true, "user defined signal 1");
+ AddSignal(31, "SIGUSR2", false, true, true, "user defined signal 2");
+ // clang-format on
}
void UnixSignals::AddSignal(int signo, const char *name, bool default_suppress,
diff --git a/contrib/llvm-project/lldb/source/Target/UnwindAssembly.cpp b/contrib/llvm-project/lldb/source/Target/UnwindAssembly.cpp
index 3a87e3da5bca..75f2b328cef8 100644
--- a/contrib/llvm-project/lldb/source/Target/UnwindAssembly.cpp
+++ b/contrib/llvm-project/lldb/source/Target/UnwindAssembly.cpp
@@ -29,5 +29,3 @@ UnwindAssemblySP UnwindAssembly::FindPlugin(const ArchSpec &arch) {
}
UnwindAssembly::UnwindAssembly(const ArchSpec &arch) : m_arch(arch) {}
-
-UnwindAssembly::~UnwindAssembly() = default;
diff --git a/contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp b/contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp
index ca1ce4b3d378..c13e2389cfed 100644
--- a/contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp
+++ b/contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp
@@ -99,8 +99,10 @@ static const CoreDefinition g_core_definitions[] = {
ArchSpec::eCore_arm_arm64, "arm64"},
{eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64,
ArchSpec::eCore_arm_armv8, "armv8"},
- {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm,
- ArchSpec::eCore_arm_armv8l, "armv8l"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_armv8l,
+ "armv8l"},
+ {eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64,
+ ArchSpec::eCore_arm_arm64e, "arm64e"},
{eByteOrderLittle, 4, 4, 4, llvm::Triple::aarch64_32,
ArchSpec::eCore_arm_arm64_32, "arm64_32"},
{eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64,
@@ -212,6 +214,11 @@ static const CoreDefinition g_core_definitions[] = {
{eByteOrderLittle, 4, 4, 4, llvm::Triple::hexagon,
ArchSpec::eCore_hexagon_hexagonv5, "hexagonv5"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::riscv32, ArchSpec::eCore_riscv32,
+ "riscv32"},
+ {eByteOrderLittle, 8, 2, 4, llvm::Triple::riscv64, ArchSpec::eCore_riscv64,
+ "riscv64"},
+
{eByteOrderLittle, 4, 4, 4, llvm::Triple::UnknownArch,
ArchSpec::eCore_uknownMach32, "unknown-mach-32"},
{eByteOrderLittle, 8, 4, 4, llvm::Triple::UnknownArch,
@@ -265,130 +272,72 @@ void ArchSpec::AutoComplete(CompletionRequest &request) {
// allows the precedence to be set when the table is built.
#define SUBTYPE_MASK 0x00FFFFFFu
+// clang-format off
static const ArchDefinitionEntry g_macho_arch_entries[] = {
- {ArchSpec::eCore_arm_generic, llvm::MachO::CPU_TYPE_ARM, CPU_ANY,
- UINT32_MAX, UINT32_MAX},
- {ArchSpec::eCore_arm_generic, llvm::MachO::CPU_TYPE_ARM, 0, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_armv4, llvm::MachO::CPU_TYPE_ARM, 5, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_armv4t, llvm::MachO::CPU_TYPE_ARM, 5, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_armv6, llvm::MachO::CPU_TYPE_ARM, 6, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_armv6m, llvm::MachO::CPU_TYPE_ARM, 14, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_armv5, llvm::MachO::CPU_TYPE_ARM, 7, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_armv5e, llvm::MachO::CPU_TYPE_ARM, 7, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_armv5t, llvm::MachO::CPU_TYPE_ARM, 7, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_xscale, llvm::MachO::CPU_TYPE_ARM, 8, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_armv7, llvm::MachO::CPU_TYPE_ARM, 9, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_armv7f, llvm::MachO::CPU_TYPE_ARM, 10, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_armv7s, llvm::MachO::CPU_TYPE_ARM, 11, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_armv7k, llvm::MachO::CPU_TYPE_ARM, 12, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_armv7m, llvm::MachO::CPU_TYPE_ARM, 15, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_armv7em, llvm::MachO::CPU_TYPE_ARM, 16, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, 1, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, 0, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, 13, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_arm_arm64_32, llvm::MachO::CPU_TYPE_ARM64_32, 0,
- UINT32_MAX, SUBTYPE_MASK},
- {ArchSpec::eCore_arm_arm64_32, llvm::MachO::CPU_TYPE_ARM64_32, 1,
- UINT32_MAX, SUBTYPE_MASK},
- {ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, CPU_ANY,
- UINT32_MAX, SUBTYPE_MASK},
- {ArchSpec::eCore_thumb, llvm::MachO::CPU_TYPE_ARM, 0, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_thumbv4t, llvm::MachO::CPU_TYPE_ARM, 5, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_thumbv5, llvm::MachO::CPU_TYPE_ARM, 7, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_thumbv5e, llvm::MachO::CPU_TYPE_ARM, 7, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_thumbv6, llvm::MachO::CPU_TYPE_ARM, 6, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_thumbv6m, llvm::MachO::CPU_TYPE_ARM, 14, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_thumbv7, llvm::MachO::CPU_TYPE_ARM, 9, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_thumbv7f, llvm::MachO::CPU_TYPE_ARM, 10, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_thumbv7s, llvm::MachO::CPU_TYPE_ARM, 11, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_thumbv7k, llvm::MachO::CPU_TYPE_ARM, 12, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_thumbv7m, llvm::MachO::CPU_TYPE_ARM, 15, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_thumbv7em, llvm::MachO::CPU_TYPE_ARM, 16, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_ppc_generic, llvm::MachO::CPU_TYPE_POWERPC, CPU_ANY,
- UINT32_MAX, UINT32_MAX},
- {ArchSpec::eCore_ppc_generic, llvm::MachO::CPU_TYPE_POWERPC, 0, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_ppc_ppc601, llvm::MachO::CPU_TYPE_POWERPC, 1, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_ppc_ppc602, llvm::MachO::CPU_TYPE_POWERPC, 2, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_ppc_ppc603, llvm::MachO::CPU_TYPE_POWERPC, 3, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_ppc_ppc603e, llvm::MachO::CPU_TYPE_POWERPC, 4, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_ppc_ppc603ev, llvm::MachO::CPU_TYPE_POWERPC, 5, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_ppc_ppc604, llvm::MachO::CPU_TYPE_POWERPC, 6, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_ppc_ppc604e, llvm::MachO::CPU_TYPE_POWERPC, 7, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_ppc_ppc620, llvm::MachO::CPU_TYPE_POWERPC, 8, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_ppc_ppc750, llvm::MachO::CPU_TYPE_POWERPC, 9, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_ppc_ppc7400, llvm::MachO::CPU_TYPE_POWERPC, 10, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_ppc_ppc7450, llvm::MachO::CPU_TYPE_POWERPC, 11, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_ppc_ppc970, llvm::MachO::CPU_TYPE_POWERPC, 100, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_ppc64_generic, llvm::MachO::CPU_TYPE_POWERPC64, 0,
- UINT32_MAX, SUBTYPE_MASK},
- {ArchSpec::eCore_ppc64le_generic, llvm::MachO::CPU_TYPE_POWERPC64, CPU_ANY,
- UINT32_MAX, SUBTYPE_MASK},
- {ArchSpec::eCore_ppc64_ppc970_64, llvm::MachO::CPU_TYPE_POWERPC64, 100,
- UINT32_MAX, SUBTYPE_MASK},
- {ArchSpec::eCore_x86_32_i386, llvm::MachO::CPU_TYPE_I386, 3, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_x86_32_i486, llvm::MachO::CPU_TYPE_I386, 4, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_x86_32_i486sx, llvm::MachO::CPU_TYPE_I386, 0x84,
- UINT32_MAX, SUBTYPE_MASK},
- {ArchSpec::eCore_x86_32_i386, llvm::MachO::CPU_TYPE_I386, CPU_ANY,
- UINT32_MAX, UINT32_MAX},
- {ArchSpec::eCore_x86_64_x86_64, llvm::MachO::CPU_TYPE_X86_64, 3, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_x86_64_x86_64, llvm::MachO::CPU_TYPE_X86_64, 4, UINT32_MAX,
- SUBTYPE_MASK},
- {ArchSpec::eCore_x86_64_x86_64h, llvm::MachO::CPU_TYPE_X86_64, 8,
- UINT32_MAX, SUBTYPE_MASK},
- {ArchSpec::eCore_x86_64_x86_64, llvm::MachO::CPU_TYPE_X86_64, CPU_ANY,
- UINT32_MAX, UINT32_MAX},
- // Catch any unknown mach architectures so we can always use the object and
- // symbol mach-o files
- {ArchSpec::eCore_uknownMach32, 0, 0, 0xFF000000u, 0x00000000u},
- {ArchSpec::eCore_uknownMach64, llvm::MachO::CPU_ARCH_ABI64, 0, 0xFF000000u,
- 0x00000000u}};
+ {ArchSpec::eCore_arm_generic, llvm::MachO::CPU_TYPE_ARM, CPU_ANY, UINT32_MAX, UINT32_MAX},
+ {ArchSpec::eCore_arm_generic, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_ALL, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv4, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V4T, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv4t, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V4T, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv6, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V6, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv6m, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V6M, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv5, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V5TEJ, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv5e, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V5TEJ, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv5t, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V5TEJ, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_xscale, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_XSCALE, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv7, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V7, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv7f, llvm::MachO::CPU_TYPE_ARM, 10, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv7s, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V7S, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv7k, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V7K, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv7m, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V7M, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv7em, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V7EM, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_arm64e, llvm::MachO::CPU_TYPE_ARM64, llvm::MachO::CPU_SUBTYPE_ARM64E, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, llvm::MachO::CPU_SUBTYPE_ARM64_V8, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, llvm::MachO::CPU_SUBTYPE_ARM64_ALL, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, 13, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_arm64_32, llvm::MachO::CPU_TYPE_ARM64_32, 0, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_arm64_32, llvm::MachO::CPU_TYPE_ARM64_32, 1, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, CPU_ANY, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_thumb, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_ALL, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv4t, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V4T, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv5, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V5, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv5e, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V5, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv6, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V6, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv6m, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V6M, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv7, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V7, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv7f, llvm::MachO::CPU_TYPE_ARM, 10, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv7s, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V7S, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv7k, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V7K, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv7m, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V7M, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv7em, llvm::MachO::CPU_TYPE_ARM, llvm::MachO::CPU_SUBTYPE_ARM_V7EM, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_generic, llvm::MachO::CPU_TYPE_POWERPC, CPU_ANY, UINT32_MAX, UINT32_MAX},
+ {ArchSpec::eCore_ppc_generic, llvm::MachO::CPU_TYPE_POWERPC, llvm::MachO::CPU_SUBTYPE_POWERPC_ALL, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc601, llvm::MachO::CPU_TYPE_POWERPC, llvm::MachO::CPU_SUBTYPE_POWERPC_601, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc602, llvm::MachO::CPU_TYPE_POWERPC, llvm::MachO::CPU_SUBTYPE_POWERPC_602, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc603, llvm::MachO::CPU_TYPE_POWERPC, llvm::MachO::CPU_SUBTYPE_POWERPC_603, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc603e, llvm::MachO::CPU_TYPE_POWERPC, llvm::MachO::CPU_SUBTYPE_POWERPC_603e, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc603ev, llvm::MachO::CPU_TYPE_POWERPC, llvm::MachO::CPU_SUBTYPE_POWERPC_603ev, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc604, llvm::MachO::CPU_TYPE_POWERPC, llvm::MachO::CPU_SUBTYPE_POWERPC_604, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc604e, llvm::MachO::CPU_TYPE_POWERPC, llvm::MachO::CPU_SUBTYPE_POWERPC_604e, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc620, llvm::MachO::CPU_TYPE_POWERPC, llvm::MachO::CPU_SUBTYPE_POWERPC_620, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc750, llvm::MachO::CPU_TYPE_POWERPC, llvm::MachO::CPU_SUBTYPE_POWERPC_750, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc7400, llvm::MachO::CPU_TYPE_POWERPC, llvm::MachO::CPU_SUBTYPE_POWERPC_7400, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc7450, llvm::MachO::CPU_TYPE_POWERPC, llvm::MachO::CPU_SUBTYPE_POWERPC_7450, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc970, llvm::MachO::CPU_TYPE_POWERPC, llvm::MachO::CPU_SUBTYPE_POWERPC_970, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc64_generic, llvm::MachO::CPU_TYPE_POWERPC64, llvm::MachO::CPU_SUBTYPE_POWERPC_ALL, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc64le_generic, llvm::MachO::CPU_TYPE_POWERPC64, CPU_ANY, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc64_ppc970_64, llvm::MachO::CPU_TYPE_POWERPC64, 100, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_x86_32_i386, llvm::MachO::CPU_TYPE_I386, llvm::MachO::CPU_SUBTYPE_I386_ALL, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_x86_32_i486, llvm::MachO::CPU_TYPE_I386, llvm::MachO::CPU_SUBTYPE_486, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_x86_32_i486sx, llvm::MachO::CPU_TYPE_I386, llvm::MachO::CPU_SUBTYPE_486SX, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_x86_32_i386, llvm::MachO::CPU_TYPE_I386, CPU_ANY, UINT32_MAX, UINT32_MAX},
+ {ArchSpec::eCore_x86_64_x86_64, llvm::MachO::CPU_TYPE_X86_64, llvm::MachO::CPU_SUBTYPE_X86_64_ALL, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_x86_64_x86_64, llvm::MachO::CPU_TYPE_X86_64, llvm::MachO::CPU_SUBTYPE_X86_ARCH1, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_x86_64_x86_64h, llvm::MachO::CPU_TYPE_X86_64, llvm::MachO::CPU_SUBTYPE_X86_64_H, UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_x86_64_x86_64, llvm::MachO::CPU_TYPE_X86_64, CPU_ANY, UINT32_MAX, UINT32_MAX},
+ // Catch any unknown mach architectures so we can always use the object and symbol mach-o files
+ {ArchSpec::eCore_uknownMach32, 0, 0, 0xFF000000u, 0x00000000u},
+ {ArchSpec::eCore_uknownMach64, llvm::MachO::CPU_ARCH_ABI64, 0, 0xFF000000u, 0x00000000u}};
+// clang-format on
static const ArchDefinition g_macho_arch_def = {
eArchTypeMachO, llvm::array_lengthof(g_macho_arch_entries),
@@ -452,6 +401,10 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = {
0xFFFFFFFFu, 0xFFFFFFFFu}, // ARC
{ArchSpec::eCore_avr, llvm::ELF::EM_AVR, LLDB_INVALID_CPUTYPE,
0xFFFFFFFFu, 0xFFFFFFFFu}, // AVR
+ {ArchSpec::eCore_riscv32, llvm::ELF::EM_RISCV,
+ ArchSpec::eRISCVSubType_riscv32, 0xFFFFFFFFu, 0xFFFFFFFFu}, // riscv32
+ {ArchSpec::eCore_riscv64, llvm::ELF::EM_RISCV,
+ ArchSpec::eRISCVSubType_riscv64, 0xFFFFFFFFu, 0xFFFFFFFFu}, // riscv64
};
static const ArchDefinition g_elf_arch_def = {
@@ -613,7 +566,7 @@ std::string ArchSpec::GetTargetABI() const {
return abi;
}
-void ArchSpec::SetFlags(std::string elf_abi) {
+void ArchSpec::SetFlags(const std::string &elf_abi) {
uint32_t flag = GetFlags();
if (IsMIPS()) {
@@ -846,6 +799,15 @@ bool ArchSpec::ContainsOnlyArch(const llvm::Triple &normalized_triple) {
}
void ArchSpec::MergeFrom(const ArchSpec &other) {
+ // ios-macabi always wins over macosx.
+ if ((GetTriple().getOS() == llvm::Triple::MacOSX ||
+ GetTriple().getOS() == llvm::Triple::UnknownOS) &&
+ other.GetTriple().getOS() == llvm::Triple::IOS &&
+ other.GetTriple().getEnvironment() == llvm::Triple::MacABI) {
+ (*this) = other;
+ return;
+ }
+
if (!TripleVendorWasSpecified() && other.TripleVendorWasSpecified())
GetTriple().setVendor(other.GetTriple().getVendor());
if (!TripleOSWasSpecified() && other.TripleOSWasSpecified())
@@ -978,6 +940,12 @@ static bool IsCompatibleEnvironment(llvm::Triple::EnvironmentType lhs,
if (lhs == rhs)
return true;
+ // Apple simulators are a different platform than what they simulate.
+ // As the environments are different at this point, if one of them is a
+ // simulator, then they are different.
+ if (lhs == llvm::Triple::Simulator || rhs == llvm::Triple::Simulator)
+ return false;
+
// If any of the environment is unknown then they are compatible
if (lhs == llvm::Triple::UnknownEnvironment ||
rhs == llvm::Triple::UnknownEnvironment)
@@ -1001,58 +969,69 @@ static bool IsCompatibleEnvironment(llvm::Triple::EnvironmentType lhs,
bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
// explicitly ignoring m_distribution_id in this method.
- if (GetByteOrder() != rhs.GetByteOrder())
+ if (GetByteOrder() != rhs.GetByteOrder() ||
+ !cores_match(GetCore(), rhs.GetCore(), true, exact_match))
return false;
- const ArchSpec::Core lhs_core = GetCore();
- const ArchSpec::Core rhs_core = rhs.GetCore();
+ const llvm::Triple &lhs_triple = GetTriple();
+ const llvm::Triple &rhs_triple = rhs.GetTriple();
+
+ const llvm::Triple::VendorType lhs_triple_vendor = lhs_triple.getVendor();
+ const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor();
+ if (lhs_triple_vendor != rhs_triple_vendor) {
+ const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified();
+ const bool lhs_vendor_specified = TripleVendorWasSpecified();
+ // Both architectures had the vendor specified, so if they aren't equal
+ // then we return false
+ if (rhs_vendor_specified && lhs_vendor_specified)
+ return false;
+
+ // Only fail if both vendor types are not unknown
+ if (lhs_triple_vendor != llvm::Triple::UnknownVendor &&
+ rhs_triple_vendor != llvm::Triple::UnknownVendor)
+ return false;
+ }
- const bool core_match = cores_match(lhs_core, rhs_core, true, exact_match);
-
- if (core_match) {
- const llvm::Triple &lhs_triple = GetTriple();
- const llvm::Triple &rhs_triple = rhs.GetTriple();
-
- const llvm::Triple::VendorType lhs_triple_vendor = lhs_triple.getVendor();
- const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor();
- if (lhs_triple_vendor != rhs_triple_vendor) {
- const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified();
- const bool lhs_vendor_specified = TripleVendorWasSpecified();
- // Both architectures had the vendor specified, so if they aren't equal
- // then we return false
- if (rhs_vendor_specified && lhs_vendor_specified)
- return false;
-
- // Only fail if both vendor types are not unknown
- if (lhs_triple_vendor != llvm::Triple::UnknownVendor &&
- rhs_triple_vendor != llvm::Triple::UnknownVendor)
- return false;
- }
+ const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS();
+ const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS();
+ const llvm::Triple::EnvironmentType lhs_triple_env =
+ lhs_triple.getEnvironment();
+ const llvm::Triple::EnvironmentType rhs_triple_env =
+ rhs_triple.getEnvironment();
+
+ if (!exact_match) {
+ // x86_64-apple-ios-macabi, x86_64-apple-macosx are compatible, no match.
+ if ((lhs_triple_os == llvm::Triple::IOS &&
+ lhs_triple_env == llvm::Triple::MacABI &&
+ rhs_triple_os == llvm::Triple::MacOSX) ||
+ (lhs_triple_os == llvm::Triple::MacOSX &&
+ rhs_triple_os == llvm::Triple::IOS &&
+ rhs_triple_env == llvm::Triple::MacABI))
+ return true;
+ }
- const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS();
- const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS();
- if (lhs_triple_os != rhs_triple_os) {
- const bool rhs_os_specified = rhs.TripleOSWasSpecified();
- const bool lhs_os_specified = TripleOSWasSpecified();
- // Both architectures had the OS specified, so if they aren't equal then
- // we return false
- if (rhs_os_specified && lhs_os_specified)
- return false;
-
- // Only fail if both os types are not unknown
- if (lhs_triple_os != llvm::Triple::UnknownOS &&
- rhs_triple_os != llvm::Triple::UnknownOS)
- return false;
- }
+ // x86_64-apple-ios-macabi and x86_64-apple-ios are not compatible.
+ if (lhs_triple_os == llvm::Triple::IOS &&
+ rhs_triple_os == llvm::Triple::IOS &&
+ (lhs_triple_env == llvm::Triple::MacABI ||
+ rhs_triple_env == llvm::Triple::MacABI) &&
+ lhs_triple_env != rhs_triple_env)
+ return false;
- const llvm::Triple::EnvironmentType lhs_triple_env =
- lhs_triple.getEnvironment();
- const llvm::Triple::EnvironmentType rhs_triple_env =
- rhs_triple.getEnvironment();
+ if (lhs_triple_os != rhs_triple_os) {
+ const bool lhs_os_specified = TripleOSWasSpecified();
+ const bool rhs_os_specified = rhs.TripleOSWasSpecified();
+ // If both OS types are specified and different, fail.
+ if (lhs_os_specified && rhs_os_specified)
+ return false;
- return IsCompatibleEnvironment(lhs_triple_env, rhs_triple_env);
+ // If the pair of os+env is both unspecified, match any other os+env combo.
+ if (!exact_match && ((!lhs_os_specified && !lhs_triple.hasEnvironment()) ||
+ (!rhs_os_specified && !rhs_triple.hasEnvironment())))
+ return true;
}
- return false;
+
+ return IsCompatibleEnvironment(lhs_triple_env, rhs_triple_env);
}
void ArchSpec::UpdateCore() {
@@ -1220,16 +1199,31 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2,
return true;
if (core2 == ArchSpec::eCore_arm_aarch64)
return true;
+ if (core2 == ArchSpec::eCore_arm_arm64e)
+ return true;
try_inverse = false;
}
break;
+ case ArchSpec::eCore_arm_arm64e:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_arm_arm64)
+ return true;
+ if (core2 == ArchSpec::eCore_arm_aarch64)
+ return true;
+ if (core2 == ArchSpec::eCore_arm_armv8)
+ return true;
+ try_inverse = false;
+ }
+ break;
case ArchSpec::eCore_arm_aarch64:
if (!enforce_exact_match) {
if (core2 == ArchSpec::eCore_arm_arm64)
return true;
if (core2 == ArchSpec::eCore_arm_armv8)
return true;
+ if (core2 == ArchSpec::eCore_arm_arm64e)
+ return true;
try_inverse = false;
}
break;
@@ -1240,6 +1234,8 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2,
return true;
if (core2 == ArchSpec::eCore_arm_armv8)
return true;
+ if (core2 == ArchSpec::eCore_arm_arm64e)
+ return true;
try_inverse = false;
}
break;
@@ -1400,7 +1396,8 @@ bool ArchSpec::IsFullySpecifiedTriple() const {
if ((user_specified_triple.getVendor() != llvm::Triple::UnknownVendor) ||
TripleVendorWasSpecified()) {
const unsigned unspecified = 0;
- if (user_specified_triple.getOSMajorVersion() != unspecified) {
+ if (!user_specified_triple.isOSDarwin() ||
+ user_specified_triple.getOSMajorVersion() != unspecified) {
user_triple_fully_specified = true;
}
}
diff --git a/contrib/llvm-project/lldb/source/Utility/Args.cpp b/contrib/llvm-project/lldb/source/Utility/Args.cpp
index f718c6f9ff1c..ed61e1c16303 100644
--- a/contrib/llvm-project/lldb/source/Utility/Args.cpp
+++ b/contrib/llvm-project/lldb/source/Utility/Args.cpp
@@ -175,6 +175,11 @@ Args::Args(const StringList &list) : Args() {
AppendArgument(arg);
}
+Args::Args(llvm::ArrayRef<llvm::StringRef> args) : Args() {
+ for (llvm::StringRef arg : args)
+ AppendArgument(arg);
+}
+
Args &Args::operator=(const Args &rhs) {
Clear();
@@ -374,12 +379,11 @@ void Args::Clear() {
m_argv.push_back(nullptr);
}
-const char *Args::GetShellSafeArgument(const FileSpec &shell,
- const char *unsafe_arg,
- std::string &safe_arg) {
+std::string Args::GetShellSafeArgument(const FileSpec &shell,
+ llvm::StringRef unsafe_arg) {
struct ShellDescriptor {
ConstString m_basename;
- const char *m_escapables;
+ llvm::StringRef m_escapables;
};
static ShellDescriptor g_Shells[] = {{ConstString("bash"), " '\"<>()&"},
@@ -387,7 +391,7 @@ const char *Args::GetShellSafeArgument(const FileSpec &shell,
{ConstString("sh"), " '\"<>()&"}};
// safe minimal set
- const char *escapables = " '\"";
+ llvm::StringRef escapables = " '\"";
if (auto basename = shell.GetFilename()) {
for (const auto &Shell : g_Shells) {
@@ -398,18 +402,15 @@ const char *Args::GetShellSafeArgument(const FileSpec &shell,
}
}
- 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(escapables, prev_pos);
- if (pos != std::string::npos) {
- safe_arg.insert(pos, 1, '\\');
- prev_pos = pos + 2;
- } else
- break;
+ std::string safe_arg;
+ safe_arg.reserve(unsafe_arg.size());
+ // Add a \ before every character that needs to be escaped.
+ for (char c : unsafe_arg) {
+ if (escapables.contains(c))
+ safe_arg.push_back('\\');
+ safe_arg.push_back(c);
}
- return safe_arg.c_str();
+ return safe_arg;
}
lldb::Encoding Args::StringToEncoding(llvm::StringRef s,
@@ -640,7 +641,6 @@ void OptionsWithRaw::SetFromString(llvm::StringRef arg_string) {
}
bool found_suffix = false;
-
while (!arg_string.empty()) {
// The length of the prefix before parsing.
std::size_t prev_prefix_length = original_args.size() - arg_string.size();
@@ -679,10 +679,8 @@ void OptionsWithRaw::SetFromString(llvm::StringRef arg_string) {
}
// If we didn't find a suffix delimiter, the whole string is the raw suffix.
- if (!found_suffix) {
- found_suffix = true;
+ if (!found_suffix)
m_suffix = std::string(original_args);
- }
}
void llvm::yaml::MappingTraits<Args::ArgEntry>::mapping(IO &io,
diff --git a/contrib/llvm-project/lldb/source/Utility/ConstString.cpp b/contrib/llvm-project/lldb/source/Utility/ConstString.cpp
index 62f79b3df7a5..11f48d0fcaba 100644
--- a/contrib/llvm-project/lldb/source/Utility/ConstString.cpp
+++ b/contrib/llvm-project/lldb/source/Utility/ConstString.cpp
@@ -308,7 +308,7 @@ void ConstString::SetString(const llvm::StringRef &s) {
}
void ConstString::SetStringWithMangledCounterpart(llvm::StringRef demangled,
- ConstString mangled) {
+ ConstString mangled) {
m_string = StringPool().GetConstCStringAndSetMangledCounterPart(
demangled, mangled.m_string);
}
diff --git a/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp b/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp
index aae48d6a4872..310d2b22b174 100644
--- a/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp
+++ b/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp
@@ -9,6 +9,7 @@
#include "lldb/Utility/ProcessInfo.h"
#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/ReproducerProvider.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/UserIDResolver.h"
@@ -347,57 +348,6 @@ void llvm::yaml::MappingTraits<ProcessInstanceInfo>::mapping(
io.mapRequired("parent-pid", Info.m_parent_pid);
}
-llvm::Expected<std::unique_ptr<ProcessInfoRecorder>>
-ProcessInfoRecorder::Create(const FileSpec &filename) {
- std::error_code ec;
- auto recorder =
- std::make_unique<ProcessInfoRecorder>(std::move(filename), ec);
- if (ec)
- return llvm::errorCodeToError(ec);
- return std::move(recorder);
-}
-
-void ProcessInfoProvider::Keep() {
- std::vector<std::string> files;
- for (auto &recorder : m_process_info_recorders) {
- recorder->Stop();
- files.push_back(recorder->GetFilename().GetPath());
- }
-
- FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
- std::error_code ec;
- llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
- if (ec)
- return;
- llvm::yaml::Output yout(os);
- yout << files;
-}
-
-void ProcessInfoProvider::Discard() { m_process_info_recorders.clear(); }
-
-ProcessInfoRecorder *ProcessInfoProvider::GetNewProcessInfoRecorder() {
- std::size_t i = m_process_info_recorders.size() + 1;
- std::string filename = (llvm::Twine(Info::name) + llvm::Twine("-") +
- llvm::Twine(i) + llvm::Twine(".yaml"))
- .str();
- auto recorder_or_error = ProcessInfoRecorder::Create(
- GetRoot().CopyByAppendingPathComponent(filename));
- if (!recorder_or_error) {
- llvm::consumeError(recorder_or_error.takeError());
- return nullptr;
- }
-
- m_process_info_recorders.push_back(std::move(*recorder_or_error));
- return m_process_info_recorders.back().get();
-}
-
-void ProcessInfoRecorder::Record(const ProcessInstanceInfoList &process_infos) {
- if (!m_record)
- return;
- llvm::yaml::Output yout(m_os);
- yout << const_cast<ProcessInstanceInfoList &>(process_infos);
- m_os.flush();
-}
llvm::Optional<ProcessInstanceInfoList>
repro::GetReplayProcessInstanceInfoList() {
@@ -425,7 +375,3 @@ repro::GetReplayProcessInstanceInfoList() {
return infos;
}
-
-char ProcessInfoProvider::ID = 0;
-const char *ProcessInfoProvider::Info::file = "process-info.yaml";
-const char *ProcessInfoProvider::Info::name = "process-info";
diff --git a/contrib/llvm-project/lldb/source/Utility/RegisterValue.cpp b/contrib/llvm-project/lldb/source/Utility/RegisterValue.cpp
index 7f545c214a4c..7848f784d8f2 100644
--- a/contrib/llvm-project/lldb/source/Utility/RegisterValue.cpp
+++ b/contrib/llvm-project/lldb/source/Utility/RegisterValue.cpp
@@ -138,36 +138,10 @@ bool 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 = *reinterpret_cast<const uint16_t *>(buffer.bytes);
- return true;
- case 4:
- scalar = *reinterpret_cast<const uint32_t *>(buffer.bytes);
+ DataExtractor data(buffer.bytes, buffer.length, buffer.byte_order, 1);
+ if (scalar.SetValueFromData(data, lldb::eEncodingUint,
+ buffer.length).Success())
return true;
- case 8:
- scalar = *reinterpret_cast<const uint64_t *>(buffer.bytes);
- return true;
- case 16:
- case 32:
- case 64:
- 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>(
- reinterpret_cast<const uint64_t *>(buffer.bytes),
- length_in_uint64));
- return true;
- }
- break;
- }
} break;
case eTypeUInt8:
case eTypeUInt16:
diff --git a/contrib/llvm-project/lldb/source/Utility/Reproducer.cpp b/contrib/llvm-project/lldb/source/Utility/Reproducer.cpp
index 7620ab2c389d..f302cce4436f 100644
--- a/contrib/llvm-project/lldb/source/Utility/Reproducer.cpp
+++ b/contrib/llvm-project/lldb/source/Utility/Reproducer.cpp
@@ -8,6 +8,8 @@
#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/ReproducerProvider.h"
+#include "lldb/Utility/Timer.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Threading.h"
@@ -72,6 +74,10 @@ llvm::Error Reproducer::Initialize(ReproducerMode mode,
return Error::success();
}
+void Reproducer::Initialize() {
+ llvm::cantFail(Initialize(repro::ReproducerMode::Off, llvm::None));
+}
+
bool Reproducer::Initialized() { return InstanceImpl().operator bool(); }
void Reproducer::Terminate() {
@@ -157,7 +163,7 @@ FileSpec Reproducer::GetReproducerPath() const {
return {};
}
-static FileSpec MakeAbsolute(FileSpec file_spec) {
+static FileSpec MakeAbsolute(const FileSpec &file_spec) {
SmallString<128> path;
file_spec.GetPath(path, false);
llvm::sys::fs::make_absolute(path);
@@ -166,14 +172,17 @@ static FileSpec MakeAbsolute(FileSpec file_spec) {
Generator::Generator(FileSpec root) : m_root(MakeAbsolute(std::move(root))) {
GetOrCreate<repro::WorkingDirectoryProvider>();
+ GetOrCreate<repro::HomeDirectoryProvider>();
}
Generator::~Generator() {
if (!m_done) {
- if (m_auto_generate)
+ if (m_auto_generate) {
Keep();
- else
+ llvm::cantFail(Finalize(GetRoot()));
+ } else {
Discard();
+ }
}
}
@@ -186,6 +195,7 @@ ProviderBase *Generator::Register(std::unique_ptr<ProviderBase> provider) {
}
void Generator::Keep() {
+ LLDB_SCOPED_TIMER();
assert(!m_done);
m_done = true;
@@ -196,6 +206,7 @@ void Generator::Keep() {
}
void Generator::Discard() {
+ LLDB_SCOPED_TIMER();
assert(!m_done);
m_done = true;
@@ -263,58 +274,148 @@ bool Loader::HasFile(StringRef file) {
return (it != m_files.end()) && (*it == file);
}
-llvm::Expected<std::unique_ptr<DataRecorder>>
-DataRecorder::Create(const FileSpec &filename) {
- std::error_code ec;
- auto recorder = std::make_unique<DataRecorder>(std::move(filename), ec);
- if (ec)
- return llvm::errorCodeToError(ec);
- return std::move(recorder);
-}
+void Verifier::Verify(
+ llvm::function_ref<void(llvm::StringRef)> error_callback,
+ llvm::function_ref<void(llvm::StringRef)> warning_callback,
+ llvm::function_ref<void(llvm::StringRef)> note_callack) const {
+ if (!m_loader) {
+ error_callback("invalid loader");
+ return;
+ }
-llvm::Expected<std::unique_ptr<YamlRecorder>>
-YamlRecorder::Create(const FileSpec &filename) {
- std::error_code ec;
- auto recorder = std::make_unique<YamlRecorder>(std::move(filename), ec);
- if (ec)
- return llvm::errorCodeToError(ec);
- return std::move(recorder);
-}
+ FileSpec vfs_mapping = m_loader->GetFile<FileProvider::Info>();
+ ErrorOr<std::unique_ptr<MemoryBuffer>> buffer =
+ vfs::getRealFileSystem()->getBufferForFile(vfs_mapping.GetPath());
+ if (!buffer) {
+ error_callback("unable to read files: " + buffer.getError().message());
+ return;
+ }
-void VersionProvider::Keep() {
- FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
- std::error_code ec;
- llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
- if (ec)
+ IntrusiveRefCntPtr<vfs::FileSystem> vfs = vfs::getVFSFromYAML(
+ std::move(buffer.get()), nullptr, vfs_mapping.GetPath());
+ if (!vfs) {
+ error_callback("unable to initialize the virtual file system");
return;
- os << m_version << "\n";
+ }
+
+ auto &redirecting_vfs = static_cast<vfs::RedirectingFileSystem &>(*vfs);
+ redirecting_vfs.setFallthrough(false);
+
+ {
+ llvm::Expected<std::string> working_dir =
+ GetDirectoryFrom<WorkingDirectoryProvider>(m_loader);
+ if (working_dir) {
+ if (!vfs->exists(*working_dir))
+ warning_callback("working directory '" + *working_dir + "' not in VFS");
+ vfs->setCurrentWorkingDirectory(*working_dir);
+ } else {
+ warning_callback("no working directory in reproducer: " +
+ toString(working_dir.takeError()));
+ }
+ }
+
+ {
+ llvm::Expected<std::string> home_dir =
+ GetDirectoryFrom<HomeDirectoryProvider>(m_loader);
+ if (home_dir) {
+ if (!vfs->exists(*home_dir))
+ warning_callback("home directory '" + *home_dir + "' not in VFS");
+ } else {
+ warning_callback("no home directory in reproducer: " +
+ toString(home_dir.takeError()));
+ }
+ }
+
+ {
+ Expected<std::string> symbol_files =
+ m_loader->LoadBuffer<SymbolFileProvider>();
+ if (symbol_files) {
+ std::vector<SymbolFileProvider::Entry> entries;
+ llvm::yaml::Input yin(*symbol_files);
+ yin >> entries;
+ for (const auto &entry : entries) {
+ if (!entry.module_path.empty() && !vfs->exists(entry.module_path)) {
+ warning_callback("'" + entry.module_path + "': module path for " +
+ entry.uuid + " not in VFS");
+ }
+ if (!entry.symbol_path.empty() && !vfs->exists(entry.symbol_path)) {
+ warning_callback("'" + entry.symbol_path + "': symbol path for " +
+ entry.uuid + " not in VFS");
+ }
+ }
+ } else {
+ llvm::consumeError(symbol_files.takeError());
+ }
+ }
+
+ // Missing files in the VFS are notes rather than warnings. Because the VFS
+ // is a snapshot, temporary files could have been removed between when they
+ // were recorded and when the reproducer was generated.
+ std::vector<llvm::StringRef> roots = redirecting_vfs.getRoots();
+ for (llvm::StringRef root : roots) {
+ std::error_code ec;
+ vfs::recursive_directory_iterator iter(*vfs, root, ec);
+ vfs::recursive_directory_iterator end;
+ for (; iter != end && !ec; iter.increment(ec)) {
+ ErrorOr<vfs::Status> status = vfs->status(iter->path());
+ if (!status)
+ note_callack("'" + iter->path().str() +
+ "': " + status.getError().message());
+ }
+ }
}
-void WorkingDirectoryProvider::Keep() {
- FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
- std::error_code ec;
- llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
- if (ec)
- return;
- os << m_cwd << "\n";
+static llvm::Error addPaths(StringRef path,
+ function_ref<void(StringRef)> callback) {
+ auto buffer = llvm::MemoryBuffer::getFile(path);
+ if (!buffer)
+ return errorCodeToError(buffer.getError());
+
+ SmallVector<StringRef, 0> paths;
+ (*buffer)->getBuffer().split(paths, '\0');
+ for (StringRef p : paths) {
+ if (!p.empty())
+ callback(p);
+ }
+
+ return errorCodeToError(llvm::sys::fs::remove(path));
}
-void FileProvider::recordInterestingDirectory(const llvm::Twine &dir) {
- if (m_collector)
- m_collector->addDirectory(dir);
+llvm::Error repro::Finalize(Loader *loader) {
+ if (!loader)
+ return make_error<StringError>("invalid loader",
+ llvm::inconvertibleErrorCode());
+
+ FileSpec reproducer_root = loader->GetRoot();
+ std::string files_path =
+ reproducer_root.CopyByAppendingPathComponent("files.txt").GetPath();
+ std::string dirs_path =
+ reproducer_root.CopyByAppendingPathComponent("dirs.txt").GetPath();
+
+ FileCollector collector(
+ reproducer_root.CopyByAppendingPathComponent("root").GetPath(),
+ reproducer_root.GetPath());
+
+ if (Error e =
+ addPaths(files_path, [&](StringRef p) { collector.addFile(p); }))
+ return e;
+
+ if (Error e =
+ addPaths(dirs_path, [&](StringRef p) { collector.addDirectory(p); }))
+ return e;
+
+ FileSpec mapping =
+ reproducer_root.CopyByAppendingPathComponent(FileProvider::Info::file);
+ if (auto ec = collector.copyFiles(/*stop_on_error=*/false))
+ return errorCodeToError(ec);
+ collector.writeMapping(mapping.GetPath());
+
+ return llvm::Error::success();
}
-void ProviderBase::anchor() {}
-char CommandProvider::ID = 0;
-char FileProvider::ID = 0;
-char ProviderBase::ID = 0;
-char VersionProvider::ID = 0;
-char WorkingDirectoryProvider::ID = 0;
-const char *CommandProvider::Info::file = "command-interpreter.yaml";
-const char *CommandProvider::Info::name = "command-interpreter";
-const char *FileProvider::Info::file = "files.yaml";
-const char *FileProvider::Info::name = "files";
-const char *VersionProvider::Info::file = "version.txt";
-const char *VersionProvider::Info::name = "version";
-const char *WorkingDirectoryProvider::Info::file = "cwd.txt";
-const char *WorkingDirectoryProvider::Info::name = "cwd";
+llvm::Error repro::Finalize(const FileSpec &root) {
+ Loader loader(root);
+ if (Error e = loader.LoadIndex())
+ return e;
+ return Finalize(&loader);
+}
diff --git a/contrib/llvm-project/lldb/source/Utility/ReproducerInstrumentation.cpp b/contrib/llvm-project/lldb/source/Utility/ReproducerInstrumentation.cpp
index 09aea69d8313..b274a10c98fd 100644
--- a/contrib/llvm-project/lldb/source/Utility/ReproducerInstrumentation.cpp
+++ b/contrib/llvm-project/lldb/source/Utility/ReproducerInstrumentation.cpp
@@ -8,6 +8,7 @@
#include "lldb/Utility/ReproducerInstrumentation.h"
#include "lldb/Utility/Reproducer.h"
+#include <limits>
#include <stdio.h>
#include <stdlib.h>
#include <thread>
@@ -84,6 +85,16 @@ template <> const char **Deserializer::Deserialize<const char **>() {
return r;
}
+void Deserializer::CheckSequence(unsigned sequence) {
+ if (m_expected_sequence && *m_expected_sequence != sequence)
+ llvm::report_fatal_error(
+ "The result does not match the preceding "
+ "function. This is probably the result of concurrent "
+ "use of the SB API during capture, which is currently not "
+ "supported.");
+ m_expected_sequence.reset();
+}
+
bool Registry::Replay(const FileSpec &file) {
auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath());
if (auto err = error_or_file.getError())
@@ -107,6 +118,7 @@ bool Registry::Replay(Deserializer &deserializer) {
setvbuf(stdout, nullptr, _IONBF, 0);
while (deserializer.HasData(1)) {
+ unsigned sequence = deserializer.Deserialize<unsigned>();
unsigned id = deserializer.Deserialize<unsigned>();
#ifndef LLDB_REPRO_INSTR_TRACE
@@ -115,6 +127,7 @@ bool Registry::Replay(Deserializer &deserializer) {
llvm::errs() << "Replaying " << id << ": " << GetSignature(id) << "\n";
#endif
+ deserializer.SetExpectedSequence(sequence);
GetReplayer(id)->operator()(deserializer);
}
@@ -181,21 +194,24 @@ unsigned ObjectToIndex::GetIndexForObjectImpl(const void *object) {
Recorder::Recorder()
: m_serializer(nullptr), m_pretty_func(), m_pretty_args(),
- m_local_boundary(false), m_result_recorded(true) {
+ m_local_boundary(false), m_result_recorded(true),
+ m_sequence(std::numeric_limits<unsigned>::max()) {
if (!g_global_boundary) {
g_global_boundary = true;
m_local_boundary = true;
+ m_sequence = GetNextSequenceNumber();
}
}
Recorder::Recorder(llvm::StringRef pretty_func, std::string &&pretty_args)
: m_serializer(nullptr), m_pretty_func(pretty_func),
m_pretty_args(pretty_args), m_local_boundary(false),
- m_result_recorded(true) {
+ m_result_recorded(true),
+ m_sequence(std::numeric_limits<unsigned>::max()) {
if (!g_global_boundary) {
g_global_boundary = true;
m_local_boundary = true;
-
+ m_sequence = GetNextSequenceNumber();
LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API), "{0} ({1})",
m_pretty_func, m_pretty_args);
}
@@ -206,6 +222,11 @@ Recorder::~Recorder() {
UpdateBoundary();
}
+unsigned Recorder::GetSequenceNumber() const {
+ assert(m_sequence != std::numeric_limits<unsigned>::max());
+ return m_sequence;
+}
+
void InstrumentationData::Initialize(Serializer &serializer,
Registry &registry) {
InstanceImpl().emplace(serializer, registry);
@@ -227,4 +248,6 @@ llvm::Optional<InstrumentationData> &InstrumentationData::InstanceImpl() {
return g_instrumentation_data;
}
-bool lldb_private::repro::Recorder::g_global_boundary;
+thread_local bool lldb_private::repro::Recorder::g_global_boundary = false;
+std::atomic<unsigned> lldb_private::repro::Recorder::g_sequence;
+std::mutex lldb_private::repro::Recorder::g_mutex;
diff --git a/contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp b/contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp
new file mode 100644
index 000000000000..ed016820db21
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Utility/ReproducerProvider.cpp
@@ -0,0 +1,221 @@
+//===-- Reproducer.cpp ----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/ReproducerProvider.h"
+#include "lldb/Utility/ProcessInfo.h"
+#include "llvm/ADT/ScopeExit.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace lldb_private;
+using namespace lldb_private::repro;
+using namespace llvm;
+using namespace llvm::yaml;
+
+llvm::Expected<std::unique_ptr<DataRecorder>>
+DataRecorder::Create(const FileSpec &filename) {
+ std::error_code ec;
+ auto recorder = std::make_unique<DataRecorder>(std::move(filename), ec);
+ if (ec)
+ return llvm::errorCodeToError(ec);
+ return std::move(recorder);
+}
+
+llvm::Expected<std::unique_ptr<YamlRecorder>>
+YamlRecorder::Create(const FileSpec &filename) {
+ std::error_code ec;
+ auto recorder = std::make_unique<YamlRecorder>(std::move(filename), ec);
+ if (ec)
+ return llvm::errorCodeToError(ec);
+ return std::move(recorder);
+}
+
+void VersionProvider::Keep() {
+ FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
+ std::error_code ec;
+ llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
+ if (ec)
+ return;
+ os << m_version << "\n";
+}
+
+FlushingFileCollector::FlushingFileCollector(llvm::StringRef files_path,
+ llvm::StringRef dirs_path,
+ std::error_code &ec) {
+ auto clear = llvm::make_scope_exit([this]() {
+ m_files_os.reset();
+ m_dirs_os.reset();
+ });
+ m_files_os.emplace(files_path, ec, llvm::sys::fs::OF_Append);
+ if (ec)
+ return;
+ m_dirs_os.emplace(dirs_path, ec, llvm::sys::fs::OF_Append);
+ if (ec)
+ return;
+ clear.release();
+}
+
+void FlushingFileCollector::addFileImpl(StringRef file) {
+ if (m_files_os) {
+ *m_files_os << file << '\0';
+ m_files_os->flush();
+ }
+}
+
+llvm::vfs::directory_iterator
+FlushingFileCollector::addDirectoryImpl(const Twine &dir,
+ IntrusiveRefCntPtr<vfs::FileSystem> vfs,
+ std::error_code &dir_ec) {
+ if (m_dirs_os) {
+ *m_dirs_os << dir << '\0';
+ m_dirs_os->flush();
+ }
+ return vfs->dir_begin(dir, dir_ec);
+}
+
+void FileProvider::RecordInterestingDirectory(const llvm::Twine &dir) {
+ if (m_collector)
+ m_collector->addFile(dir);
+}
+
+void FileProvider::RecordInterestingDirectoryRecursive(const llvm::Twine &dir) {
+ if (m_collector)
+ m_collector->addDirectory(dir);
+}
+
+llvm::Expected<std::unique_ptr<ProcessInfoRecorder>>
+ProcessInfoRecorder::Create(const FileSpec &filename) {
+ std::error_code ec;
+ auto recorder =
+ std::make_unique<ProcessInfoRecorder>(std::move(filename), ec);
+ if (ec)
+ return llvm::errorCodeToError(ec);
+ return std::move(recorder);
+}
+
+void ProcessInfoProvider::Keep() {
+ std::vector<std::string> files;
+ for (auto &recorder : m_process_info_recorders) {
+ recorder->Stop();
+ files.push_back(recorder->GetFilename().GetPath());
+ }
+
+ FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
+ std::error_code ec;
+ llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
+ if (ec)
+ return;
+ llvm::yaml::Output yout(os);
+ yout << files;
+}
+
+void ProcessInfoProvider::Discard() { m_process_info_recorders.clear(); }
+
+ProcessInfoRecorder *ProcessInfoProvider::GetNewProcessInfoRecorder() {
+ std::size_t i = m_process_info_recorders.size() + 1;
+ std::string filename = (llvm::Twine(Info::name) + llvm::Twine("-") +
+ llvm::Twine(i) + llvm::Twine(".yaml"))
+ .str();
+ auto recorder_or_error = ProcessInfoRecorder::Create(
+ GetRoot().CopyByAppendingPathComponent(filename));
+ if (!recorder_or_error) {
+ llvm::consumeError(recorder_or_error.takeError());
+ return nullptr;
+ }
+
+ m_process_info_recorders.push_back(std::move(*recorder_or_error));
+ return m_process_info_recorders.back().get();
+}
+
+void ProcessInfoRecorder::Record(const ProcessInstanceInfoList &process_infos) {
+ if (!m_record)
+ return;
+ llvm::yaml::Output yout(m_os);
+ yout << const_cast<ProcessInstanceInfoList &>(process_infos);
+ m_os.flush();
+}
+
+void SymbolFileProvider::AddSymbolFile(const UUID *uuid,
+ const FileSpec &module_file,
+ const FileSpec &symbol_file) {
+ if (!uuid || (!module_file && !symbol_file))
+ return;
+ m_symbol_files.emplace_back(uuid->GetAsString(), module_file.GetPath(),
+ symbol_file.GetPath());
+}
+
+void SymbolFileProvider::Keep() {
+ FileSpec file = this->GetRoot().CopyByAppendingPathComponent(Info::file);
+ std::error_code ec;
+ llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
+ if (ec)
+ return;
+
+ // Remove duplicates.
+ llvm::sort(m_symbol_files.begin(), m_symbol_files.end());
+ m_symbol_files.erase(
+ std::unique(m_symbol_files.begin(), m_symbol_files.end()),
+ m_symbol_files.end());
+
+ llvm::yaml::Output yout(os);
+ yout << m_symbol_files;
+}
+
+SymbolFileLoader::SymbolFileLoader(Loader *loader) {
+ if (!loader)
+ return;
+
+ FileSpec file = loader->GetFile<SymbolFileProvider::Info>();
+ if (!file)
+ return;
+
+ auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath());
+ if (auto err = error_or_file.getError())
+ return;
+
+ llvm::yaml::Input yin((*error_or_file)->getBuffer());
+ yin >> m_symbol_files;
+}
+
+std::pair<FileSpec, FileSpec>
+SymbolFileLoader::GetPaths(const UUID *uuid) const {
+ if (!uuid)
+ return {};
+
+ auto it = std::lower_bound(m_symbol_files.begin(), m_symbol_files.end(),
+ SymbolFileProvider::Entry(uuid->GetAsString()));
+ if (it == m_symbol_files.end())
+ return {};
+ return std::make_pair<FileSpec, FileSpec>(FileSpec(it->module_path),
+ FileSpec(it->symbol_path));
+}
+
+void ProviderBase::anchor() {}
+char CommandProvider::ID = 0;
+char FileProvider::ID = 0;
+char ProviderBase::ID = 0;
+char VersionProvider::ID = 0;
+char WorkingDirectoryProvider::ID = 0;
+char HomeDirectoryProvider::ID = 0;
+char ProcessInfoProvider::ID = 0;
+char SymbolFileProvider::ID = 0;
+const char *CommandProvider::Info::file = "command-interpreter.yaml";
+const char *CommandProvider::Info::name = "command-interpreter";
+const char *FileProvider::Info::file = "files.yaml";
+const char *FileProvider::Info::name = "files";
+const char *VersionProvider::Info::file = "version.txt";
+const char *VersionProvider::Info::name = "version";
+const char *WorkingDirectoryProvider::Info::file = "cwd.txt";
+const char *WorkingDirectoryProvider::Info::name = "cwd";
+const char *HomeDirectoryProvider::Info::file = "home.txt";
+const char *HomeDirectoryProvider::Info::name = "home";
+const char *ProcessInfoProvider::Info::file = "process-info.yaml";
+const char *ProcessInfoProvider::Info::name = "process-info";
+const char *SymbolFileProvider::Info::file = "symbol-files.yaml";
+const char *SymbolFileProvider::Info::name = "symbol-files";
diff --git a/contrib/llvm-project/lldb/source/Utility/Scalar.cpp b/contrib/llvm-project/lldb/source/Utility/Scalar.cpp
index 6c48bbde532f..9bf633d0c4e0 100644
--- a/contrib/llvm-project/lldb/source/Utility/Scalar.cpp
+++ b/contrib/llvm-project/lldb/source/Utility/Scalar.cpp
@@ -25,109 +25,62 @@ using namespace lldb_private;
using llvm::APFloat;
using llvm::APInt;
+using llvm::APSInt;
-namespace {
-enum class Category { Void, Integral, Float };
-}
-
-static Category GetCategory(Scalar::Type type) {
- switch (type) {
- case Scalar::e_void:
- return Category::Void;
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- return Category::Float;
- case Scalar::e_sint:
- case Scalar::e_slong:
- case Scalar::e_slonglong:
- case Scalar::e_sint128:
- case Scalar::e_sint256:
- case Scalar::e_sint512:
- case Scalar::e_uint:
- case Scalar::e_ulong:
- case Scalar::e_ulonglong:
- case Scalar::e_uint128:
- case Scalar::e_uint256:
- case Scalar::e_uint512:
- return Category::Integral;
+Scalar::PromotionKey Scalar::GetPromoKey() const {
+ switch (m_type) {
+ case e_void:
+ return PromotionKey{e_void, 0, false};
+ case e_int:
+ return PromotionKey{e_int, m_integer.getBitWidth(), m_integer.isUnsigned()};
+ case e_float:
+ return GetFloatPromoKey(m_float.getSemantics());
}
- llvm_unreachable("Unhandled type!");
+ llvm_unreachable("Unhandled category!");
}
-static bool IsSigned(Scalar::Type type) {
- switch (type) {
- case Scalar::e_void:
- case Scalar::e_uint:
- case Scalar::e_ulong:
- case Scalar::e_ulonglong:
- case Scalar::e_uint128:
- case Scalar::e_uint256:
- case Scalar::e_uint512:
- return false;
- case Scalar::e_sint:
- case Scalar::e_slong:
- case Scalar::e_slonglong:
- case Scalar::e_sint128:
- case Scalar::e_sint256:
- case Scalar::e_sint512:
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- return true;
+Scalar::PromotionKey Scalar::GetFloatPromoKey(const llvm::fltSemantics &sem) {
+ static const llvm::fltSemantics *const order[] = {
+ &APFloat::IEEEsingle(), &APFloat::IEEEdouble(),
+ &APFloat::x87DoubleExtended()};
+ for (const auto &entry : llvm::enumerate(order)) {
+ if (entry.value() == &sem)
+ return PromotionKey{e_float, entry.index(), false};
}
- llvm_unreachable("Unhandled type!");
+ llvm_unreachable("Unsupported semantics!");
}
-
// Promote to max type currently follows the ANSI C rule for type promotion in
// expressions.
-static Scalar::Type PromoteToMaxType(
- const Scalar &lhs, // The const left hand side object
- const Scalar &rhs, // The const right hand side object
- Scalar &temp_value, // A modifiable temp value than can be used to hold
- // either the promoted lhs or rhs object
- const Scalar *&promoted_lhs_ptr, // Pointer to the resulting possibly
- // promoted value of lhs (at most one of
- // lhs/rhs will get promoted)
- const Scalar *&promoted_rhs_ptr // Pointer to the resulting possibly
- // promoted value of rhs (at most one of
- // lhs/rhs will get promoted)
-) {
- Scalar result;
- // Initialize the promoted values for both the right and left hand side
- // values to be the objects themselves. If no promotion is needed (both right
- // and left have the same type), then the temp_value will not get used.
- promoted_lhs_ptr = &lhs;
- promoted_rhs_ptr = &rhs;
- // Extract the types of both the right and left hand side values
- Scalar::Type lhs_type = lhs.GetType();
- Scalar::Type rhs_type = rhs.GetType();
-
- if (lhs_type > rhs_type) {
- // Right hand side need to be promoted
- temp_value = rhs; // Copy right hand side into the temp value
- if (temp_value.Promote(lhs_type)) // Promote it
- promoted_rhs_ptr =
- &temp_value; // Update the pointer for the promoted right hand side
- } else if (lhs_type < rhs_type) {
- // Left hand side need to be promoted
- temp_value = lhs; // Copy left hand side value into the temp value
- if (temp_value.Promote(rhs_type)) // Promote it
- promoted_lhs_ptr =
- &temp_value; // Update the pointer for the promoted left hand side
- }
+Scalar::Type Scalar::PromoteToMaxType(Scalar &lhs, Scalar &rhs) {
+ const auto &Promote = [](Scalar &a, const Scalar &b) {
+ switch (b.GetType()) {
+ case e_void:
+ break;
+ case e_int:
+ a.IntegralPromote(b.m_integer.getBitWidth(), b.m_integer.isSigned());
+ break;
+ case e_float:
+ a.FloatPromote(b.m_float.getSemantics());
+ }
+ };
+
+ PromotionKey lhs_key = lhs.GetPromoKey();
+ PromotionKey rhs_key = rhs.GetPromoKey();
+
+ if (lhs_key > rhs_key)
+ Promote(rhs, lhs);
+ else if (rhs_key > lhs_key)
+ Promote(lhs, rhs);
// Make sure our type promotion worked as expected
- if (promoted_lhs_ptr->GetType() == promoted_rhs_ptr->GetType())
- return promoted_lhs_ptr->GetType(); // Return the resulting max type
+ if (lhs.GetPromoKey() == rhs.GetPromoKey())
+ return lhs.GetType(); // Return the resulting type
// Return the void type (zero) if we fail to promote either of the values.
return Scalar::e_void;
}
-Scalar::Scalar() : m_type(e_void), m_float(static_cast<float>(0)) {}
-
bool Scalar::GetData(DataExtractor &data, size_t limit_byte_size) const {
size_t byte_size = GetByteSize();
if (byte_size == 0) {
@@ -160,16 +113,16 @@ bool Scalar::GetData(DataExtractor &data, size_t limit_byte_size) const {
void Scalar::GetBytes(llvm::MutableArrayRef<uint8_t> storage) const {
assert(storage.size() >= GetByteSize());
- const auto &store = [&](const llvm::APInt val) {
+ const auto &store = [&](const llvm::APInt &val) {
StoreIntToMemory(val, storage.data(), (val.getBitWidth() + 7) / 8);
};
- switch (GetCategory(m_type)) {
- case Category::Void:
+ switch (m_type) {
+ case e_void:
break;
- case Category::Integral:
+ case e_int:
store(m_integer);
break;
- case Category::Float:
+ case e_float:
store(m_float.bitcastToAPInt());
break;
}
@@ -179,36 +132,21 @@ size_t Scalar::GetByteSize() 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:
- case e_sint512:
- case e_uint512:
+ case e_int:
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);
+ return m_float.bitcastToAPInt().getBitWidth() / 8;
}
return 0;
}
bool Scalar::IsZero() const {
- switch (GetCategory(m_type)) {
- case Category::Void:
+ switch (m_type) {
+ case e_void:
break;
- case Category::Integral:
+ case e_int:
return m_integer.isNullValue();
- case Category::Float:
+ case e_float:
return m_float.isZero();
}
return false;
@@ -218,13 +156,13 @@ void Scalar::GetValue(Stream *s, bool show_type) const {
if (show_type)
s->Printf("(%s) ", GetTypeAsCString());
- switch (GetCategory(m_type)) {
- case Category::Void:
+ switch (m_type) {
+ case e_void:
break;
- case Category::Integral:
- s->PutCString(m_integer.toString(10, IsSigned(m_type)));
+ case e_int:
+ s->PutCString(m_integer.toString(10));
break;
- case Category::Float:
+ case e_float:
llvm::SmallString<24> string;
m_float.toString(string);
s->PutCString(string);
@@ -232,137 +170,47 @@ void Scalar::GetValue(Stream *s, bool show_type) const {
}
}
-Scalar::~Scalar() = default;
-
-Scalar::Type Scalar::GetBestTypeForBitSize(size_t bit_size, bool sign) {
- // Scalar types are always host types, hence the sizeof().
- if (sign) {
- if (bit_size <= sizeof(int)*8) return Scalar::e_sint;
- if (bit_size <= sizeof(long)*8) return Scalar::e_slong;
- if (bit_size <= sizeof(long long)*8) return Scalar::e_slonglong;
- if (bit_size <= 128) return Scalar::e_sint128;
- if (bit_size <= 256) return Scalar::e_sint256;
- if (bit_size <= 512) return Scalar::e_sint512;
- } else {
- if (bit_size <= sizeof(unsigned int)*8) return Scalar::e_uint;
- if (bit_size <= sizeof(unsigned long)*8) return Scalar::e_ulong;
- if (bit_size <= sizeof(unsigned long long)*8) return Scalar::e_ulonglong;
- if (bit_size <= 128) return Scalar::e_uint128;
- if (bit_size <= 256) return Scalar::e_uint256;
- if (bit_size <= 512) return Scalar::e_uint512;
- }
- return Scalar::e_void;
-}
-
void Scalar::TruncOrExtendTo(uint16_t bits, bool sign) {
- m_integer = sign ? m_integer.sextOrTrunc(bits) : m_integer.zextOrTrunc(bits);
- m_type = GetBestTypeForBitSize(bits, sign);
-}
-
-static size_t GetBitSize(Scalar::Type type) {
- switch (type) {
- case Scalar::e_void:
- return 0;
- case Scalar::e_sint:
- return 8 * sizeof(int);
- case Scalar::e_uint:
- return 8 * sizeof(unsigned int);
- case Scalar::e_slong:
- return 8 * sizeof(long);
- case Scalar::e_ulong:
- return 8 * sizeof(unsigned long);
- case Scalar::e_slonglong:
- return 8 * sizeof(long long);
- case Scalar::e_ulonglong:
- return 8 * sizeof(unsigned long long);
- case Scalar::e_sint128:
- case Scalar::e_uint128:
- return BITWIDTH_INT128;
- case Scalar::e_sint256:
- case Scalar::e_uint256:
- return BITWIDTH_INT256;
- case Scalar::e_sint512:
- case Scalar::e_uint512:
- return BITWIDTH_INT512;
- case Scalar::e_float:
- return 8 * sizeof(float);
- case Scalar::e_double:
- return 8 * sizeof(double);
- case Scalar::e_long_double:
- return 8 * sizeof(long double);
- }
- llvm_unreachable("Unhandled type!");
+ m_integer.setIsSigned(sign);
+ m_integer = m_integer.extOrTrunc(bits);
}
-static const llvm::fltSemantics &GetFltSemantics(Scalar::Type type) {
- switch (type) {
- case Scalar::e_void:
- case Scalar::e_sint:
- case Scalar::e_slong:
- case Scalar::e_slonglong:
- case Scalar::e_sint128:
- case Scalar::e_sint256:
- case Scalar::e_sint512:
- case Scalar::e_uint:
- case Scalar::e_ulong:
- case Scalar::e_ulonglong:
- case Scalar::e_uint128:
- case Scalar::e_uint256:
- case Scalar::e_uint512:
- llvm_unreachable("Only floating point types supported!");
- case Scalar::e_float:
- return llvm::APFloat::IEEEsingle();
- case Scalar::e_double:
- return llvm::APFloat::IEEEdouble();
- case Scalar::e_long_double:
- return llvm::APFloat::x87DoubleExtended();
+bool Scalar::IntegralPromote(uint16_t bits, bool sign) {
+ switch (m_type) {
+ case e_void:
+ case e_float:
+ break;
+ case e_int:
+ if (GetPromoKey() > PromotionKey(e_int, bits, !sign))
+ break;
+ m_integer = m_integer.extOrTrunc(bits);
+ m_integer.setIsSigned(sign);
+ return true;
}
- llvm_unreachable("Unhandled type!");
+ return false;
}
-bool Scalar::Promote(Scalar::Type type) {
+bool Scalar::FloatPromote(const llvm::fltSemantics &semantics) {
bool success = false;
- switch (GetCategory(m_type)) {
- case Category::Void:
+ switch (m_type) {
+ case e_void:
break;
- case Category::Integral:
- switch (GetCategory(type)) {
- case Category::Void:
- break;
- case Category::Integral:
- if (type < m_type)
- break;
- success = true;
- if (IsSigned(m_type))
- m_integer = m_integer.sextOrTrunc(GetBitSize(type));
- else
- m_integer = m_integer.zextOrTrunc(GetBitSize(type));
- break;
- case Category::Float:
- m_float = llvm::APFloat(GetFltSemantics(type));
- m_float.convertFromAPInt(m_integer, IsSigned(m_type),
- llvm::APFloat::rmNearestTiesToEven);
- success = true;
- break;
- }
+ case e_int:
+ m_float = llvm::APFloat(semantics);
+ m_float.convertFromAPInt(m_integer, m_integer.isSigned(),
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
break;
- case Category::Float:
- switch (GetCategory(type)) {
- case Category::Void:
- case Category::Integral:
+ case e_float:
+ if (GetFloatPromoKey(semantics) < GetFloatPromoKey(m_float.getSemantics()))
break;
- case Category::Float:
- if (type < m_type)
- break;
- bool ignore;
- success = true;
- m_float.convert(GetFltSemantics(type), llvm::APFloat::rmNearestTiesToEven,
- &ignore);
- }
+ bool ignore;
+ success = true;
+ m_float.convert(semantics, llvm::APFloat::rmNearestTiesToEven, &ignore);
}
if (success)
- m_type = type;
+ m_type = e_float;
return success;
}
@@ -370,70 +218,24 @@ const char *Scalar::GetValueTypeAsCString(Scalar::Type type) {
switch (type) {
case e_void:
return "void";
- case e_sint:
+ case e_int:
return "int";
- case e_uint:
- return "unsigned int";
- case e_slong:
- return "long";
- case e_ulong:
- return "unsigned long";
- case e_slonglong:
- return "long long";
- case e_ulonglong:
- return "unsigned long long";
case e_float:
return "float";
- case e_double:
- return "double";
- 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";
- case e_sint512:
- return "int512_t";
- case e_uint512:
- return "uint512_t";
}
return "???";
}
-Scalar::Type
-Scalar::GetValueTypeForSignedIntegerWithByteSize(size_t byte_size) {
- if (byte_size <= sizeof(sint_t))
- return e_sint;
- if (byte_size <= sizeof(slong_t))
- return e_slong;
- if (byte_size <= sizeof(slonglong_t))
- return e_slonglong;
- return e_void;
-}
-
-Scalar::Type
-Scalar::GetValueTypeForUnsignedIntegerWithByteSize(size_t byte_size) {
- if (byte_size <= sizeof(uint_t))
- return e_uint;
- if (byte_size <= sizeof(ulong_t))
- return e_ulong;
- if (byte_size <= sizeof(ulonglong_t))
- return e_ulonglong;
- return e_void;
-}
-
-Scalar::Type Scalar::GetValueTypeForFloatWithByteSize(size_t byte_size) {
- if (byte_size == sizeof(float_t))
- return e_float;
- if (byte_size == sizeof(double_t))
- return e_double;
- if (byte_size == sizeof(long_double_t))
- return e_long_double;
- return e_void;
+bool Scalar::IsSigned() const {
+ switch (m_type) {
+ case e_void:
+ return false;
+ case e_int:
+ return m_integer.isSigned();
+ case e_float:
+ return true;
+ }
+ llvm_unreachable("Unrecognized type!");
}
bool Scalar::MakeSigned() {
@@ -442,57 +244,13 @@ bool Scalar::MakeSigned() {
switch (m_type) {
case e_void:
break;
- case e_sint:
- success = true;
- break;
- case e_uint:
- m_type = e_sint;
- success = true;
- break;
- case e_slong:
- success = true;
- break;
- case e_ulong:
- m_type = e_slong;
- success = true;
- break;
- 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_sint128;
- success = true;
- break;
- case e_sint256:
- success = true;
- break;
- case e_uint256:
- m_type = e_sint256;
- success = true;
- break;
- case e_sint512:
- success = true;
- break;
- case e_uint512:
- m_type = e_sint512;
+ case e_int:
+ m_integer.setIsSigned(true);
success = true;
break;
case e_float:
success = true;
break;
- case e_double:
- success = true;
- break;
- case e_long_double:
- success = true;
- break;
}
return success;
@@ -504,57 +262,13 @@ bool Scalar::MakeUnsigned() {
switch (m_type) {
case e_void:
break;
- case e_sint:
- m_type = e_uint;
- success = true;
- break;
- case e_uint:
- success = true;
- break;
- case e_slong:
- m_type = e_ulong;
- success = true;
- break;
- case e_ulong:
- success = true;
- break;
- case e_slonglong:
- m_type = e_ulonglong;
- success = true;
- break;
- case e_ulonglong:
- success = true;
- break;
- case e_sint128:
- m_type = e_uint128;
- success = true;
- break;
- case e_uint128:
- success = true;
- break;
- case e_sint256:
- m_type = e_uint256;
- success = true;
- break;
- case e_uint256:
- success = true;
- break;
- case e_sint512:
- m_type = e_uint512;
- success = true;
- break;
- case e_uint512:
+ case e_int:
+ m_integer.setIsUnsigned(true);
success = true;
break;
case e_float:
success = true;
break;
- case e_double:
- success = true;
- break;
- case e_long_double:
- success = true;
- break;
}
return success;
@@ -569,14 +283,16 @@ static llvm::APInt ToAPInt(const llvm::APFloat &f, unsigned bits,
}
template <typename T> T Scalar::GetAs(T fail_value) const {
- switch (GetCategory(m_type)) {
- case Category::Void:
+ switch (m_type) {
+ case e_void:
break;
- case Category::Integral:
- if (IsSigned(m_type))
- return m_integer.sextOrTrunc(sizeof(T) * 8).getSExtValue();
- return m_integer.zextOrTrunc(sizeof(T) * 8).getZExtValue();
- case Category::Float:
+ case e_int: {
+ APSInt ext = m_integer.extOrTrunc(sizeof(T) * 8);
+ if (ext.isSigned())
+ return ext.getSExtValue();
+ return ext.getZExtValue();
+ }
+ case e_float:
return ToAPInt(m_float, sizeof(T) * 8, std::is_unsigned<T>::value)
.getSExtValue();
}
@@ -620,39 +336,39 @@ unsigned long long Scalar::ULongLong(unsigned long long fail_value) const {
}
llvm::APInt Scalar::SInt128(const llvm::APInt &fail_value) const {
- switch (GetCategory(m_type)) {
- case Category::Void:
+ switch (m_type) {
+ case e_void:
break;
- case Category::Integral:
+ case e_int:
return m_integer;
- case Category::Float:
+ case e_float:
return ToAPInt(m_float, 128, /*is_unsigned=*/false);
}
return fail_value;
}
llvm::APInt Scalar::UInt128(const llvm::APInt &fail_value) const {
- switch (GetCategory(m_type)) {
- case Category::Void:
+ switch (m_type) {
+ case e_void:
break;
- case Category::Integral:
+ case e_int:
return m_integer;
- case Category::Float:
+ case e_float:
return ToAPInt(m_float, 128, /*is_unsigned=*/true);
}
return fail_value;
}
float Scalar::Float(float fail_value) const {
- switch (GetCategory(m_type)) {
- case Category::Void:
+ switch (m_type) {
+ case e_void:
break;
- case Category::Integral:
- if (IsSigned(m_type))
+ case e_int:
+ if (m_integer.isSigned())
return llvm::APIntOps::RoundSignedAPIntToFloat(m_integer);
return llvm::APIntOps::RoundAPIntToFloat(m_integer);
- case Category::Float: {
+ case e_float: {
APFloat result = m_float;
bool losesInfo;
result.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven,
@@ -664,15 +380,15 @@ float Scalar::Float(float fail_value) const {
}
double Scalar::Double(double fail_value) const {
- switch (GetCategory(m_type)) {
- case Category::Void:
+ switch (m_type) {
+ case e_void:
break;
- case Category::Integral:
- if (IsSigned(m_type))
+ case e_int:
+ if (m_integer.isSigned())
return llvm::APIntOps::RoundSignedAPIntToDouble(m_integer);
return llvm::APIntOps::RoundAPIntToDouble(m_integer);
- case Category::Float: {
+ case e_float: {
APFloat result = m_float;
bool losesInfo;
result.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
@@ -688,21 +404,18 @@ long double Scalar::LongDouble(long double fail_value) const {
return static_cast<long double>(Double(fail_value));
}
-Scalar &Scalar::operator+=(const Scalar &rhs) {
- Scalar temp_value;
- const Scalar *a;
- const Scalar *b;
- if ((m_type = PromoteToMaxType(*this, rhs, temp_value, a, b)) !=
- Scalar::e_void) {
- switch (GetCategory(m_type)) {
- case Category::Void:
+Scalar &Scalar::operator+=(Scalar rhs) {
+ Scalar copy = *this;
+ if ((m_type = PromoteToMaxType(copy, rhs)) != Scalar::e_void) {
+ switch (m_type) {
+ case e_void:
break;
- case Category::Integral:
- m_integer = a->m_integer + b->m_integer;
+ case e_int:
+ m_integer = copy.m_integer + rhs.m_integer;
break;
- case Category::Float:
- m_float = a->m_float + b->m_float;
+ case e_float:
+ m_float = copy.m_float + rhs.m_float;
break;
}
}
@@ -710,17 +423,15 @@ Scalar &Scalar::operator+=(const Scalar &rhs) {
}
Scalar &Scalar::operator<<=(const Scalar &rhs) {
- if (GetCategory(m_type) == Category::Integral &&
- GetCategory(rhs.m_type) == Category::Integral)
- m_integer <<= rhs.m_integer;
+ if (m_type == e_int && rhs.m_type == e_int)
+ static_cast<APInt &>(m_integer) <<= rhs.m_integer;
else
m_type = e_void;
return *this;
}
bool Scalar::ShiftRightLogical(const Scalar &rhs) {
- if (GetCategory(m_type) == Category::Integral &&
- GetCategory(rhs.m_type) == Category::Integral) {
+ if (m_type == e_int && rhs.m_type == e_int) {
m_integer = m_integer.lshr(rhs.m_integer);
return true;
}
@@ -732,42 +443,16 @@ Scalar &Scalar::operator>>=(const Scalar &rhs) {
switch (m_type) {
case e_void:
case e_float:
- case e_double:
- case e_long_double:
m_type = 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:
- case e_sint512:
- case e_uint512:
+ case e_int:
switch (rhs.m_type) {
case e_void:
case e_float:
- case e_double:
- case e_long_double:
m_type = 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:
- case e_sint512:
- case e_uint512:
+ case e_int:
m_integer = m_integer.ashr(rhs.m_integer);
break;
}
@@ -777,8 +462,7 @@ Scalar &Scalar::operator>>=(const Scalar &rhs) {
}
Scalar &Scalar::operator&=(const Scalar &rhs) {
- if (GetCategory(m_type) == Category::Integral &&
- GetCategory(rhs.m_type) == Category::Integral)
+ if (m_type == e_int && rhs.m_type == e_int)
m_integer &= rhs.m_integer;
else
m_type = e_void;
@@ -790,26 +474,12 @@ bool Scalar::AbsoluteValue() {
case e_void:
break;
- case e_sint:
- case e_slong:
- case e_slonglong:
- case e_sint128:
- case e_sint256:
- case e_sint512:
+ case e_int:
if (m_integer.isNegative())
m_integer = -m_integer;
return true;
- case e_uint:
- case e_ulong:
- case e_ulonglong:
- return true;
- case e_uint128:
- case e_uint256:
- case e_uint512:
case e_float:
- case e_double:
- case e_long_double:
m_float.clearSign();
return true;
}
@@ -817,13 +487,13 @@ bool Scalar::AbsoluteValue() {
}
bool Scalar::UnaryNegate() {
- switch (GetCategory(m_type)) {
- case Category::Void:
+ switch (m_type) {
+ case e_void:
break;
- case Category::Integral:
+ case e_int:
m_integer = -m_integer;
return true;
- case Category::Float:
+ case e_float:
m_float.changeSign();
return true;
}
@@ -831,7 +501,7 @@ bool Scalar::UnaryNegate() {
}
bool Scalar::OnesComplement() {
- if (GetCategory(m_type) == Category::Integral) {
+ if (m_type == e_int) {
m_integer = ~m_integer;
return true;
}
@@ -845,46 +515,35 @@ const Scalar lldb_private::operator+(const Scalar &lhs, const Scalar &rhs) {
return result;
}
-const Scalar lldb_private::operator-(const Scalar &lhs, const Scalar &rhs) {
+const Scalar lldb_private::operator-(Scalar lhs, Scalar rhs) {
Scalar result;
- Scalar temp_value;
- const Scalar *a;
- const Scalar *b;
- if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
- Scalar::e_void) {
- switch (GetCategory(result.m_type)) {
- case Category::Void:
+ if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
+ switch (result.m_type) {
+ case Scalar::e_void:
break;
- case Category::Integral:
- result.m_integer = a->m_integer - b->m_integer;
+ case Scalar::e_int:
+ result.m_integer = lhs.m_integer - rhs.m_integer;
break;
- case Category::Float:
- result.m_float = a->m_float - b->m_float;
+ case Scalar::e_float:
+ result.m_float = lhs.m_float - rhs.m_float;
break;
}
}
return result;
}
-const Scalar lldb_private::operator/(const Scalar &lhs, const Scalar &rhs) {
+const Scalar lldb_private::operator/(Scalar lhs, Scalar rhs) {
Scalar result;
- Scalar temp_value;
- const Scalar *a;
- const Scalar *b;
- if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
- Scalar::e_void &&
- !b->IsZero()) {
- switch (GetCategory(result.m_type)) {
- case Category::Void:
+ if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void &&
+ !rhs.IsZero()) {
+ switch (result.m_type) {
+ case Scalar::e_void:
break;
- case Category::Integral:
- if (IsSigned(result.m_type))
- result.m_integer = a->m_integer.sdiv(b->m_integer);
- else
- result.m_integer = a->m_integer.udiv(b->m_integer);
+ case Scalar::e_int:
+ result.m_integer = lhs.m_integer / rhs.m_integer;
return result;
- case Category::Float:
- result.m_float = a->m_float / b->m_float;
+ case Scalar::e_float:
+ result.m_float = lhs.m_float / rhs.m_float;
return result;
}
}
@@ -894,69 +553,50 @@ const Scalar lldb_private::operator/(const Scalar &lhs, const Scalar &rhs) {
return result;
}
-const Scalar lldb_private::operator*(const Scalar &lhs, const Scalar &rhs) {
+const Scalar lldb_private::operator*(Scalar lhs, Scalar rhs) {
Scalar result;
- Scalar temp_value;
- const Scalar *a;
- const Scalar *b;
- if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
- Scalar::e_void) {
- switch (GetCategory(result.m_type)) {
- case Category::Void:
+ if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
+ switch (result.m_type) {
+ case Scalar::e_void:
break;
- case Category::Integral:
- result.m_integer = a->m_integer * b->m_integer;
+ case Scalar::e_int:
+ result.m_integer = lhs.m_integer * rhs.m_integer;
break;
- case Category::Float:
- result.m_float = a->m_float * b->m_float;
+ case Scalar::e_float:
+ result.m_float = lhs.m_float * rhs.m_float;
break;
}
}
return result;
}
-const Scalar lldb_private::operator&(const Scalar &lhs, const Scalar &rhs) {
+const Scalar lldb_private::operator&(Scalar lhs, Scalar rhs) {
Scalar result;
- Scalar temp_value;
- const Scalar *a;
- const Scalar *b;
- if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
- Scalar::e_void) {
- if (GetCategory(result.m_type) == Category::Integral)
- result.m_integer = a->m_integer & b->m_integer;
+ if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
+ if (result.m_type == Scalar::e_int)
+ result.m_integer = lhs.m_integer & rhs.m_integer;
else
result.m_type = Scalar::e_void;
}
return result;
}
-const Scalar lldb_private::operator|(const Scalar &lhs, const Scalar &rhs) {
+const Scalar lldb_private::operator|(Scalar lhs, Scalar rhs) {
Scalar result;
- Scalar temp_value;
- const Scalar *a;
- const Scalar *b;
- if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
- Scalar::e_void) {
- if (GetCategory(result.m_type) == Category::Integral)
- result.m_integer = a->m_integer | b->m_integer;
+ if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
+ if (result.m_type == Scalar::e_int)
+ result.m_integer = lhs.m_integer | rhs.m_integer;
else
result.m_type = Scalar::e_void;
}
return result;
}
-const Scalar lldb_private::operator%(const Scalar &lhs, const Scalar &rhs) {
+const Scalar lldb_private::operator%(Scalar lhs, Scalar rhs) {
Scalar result;
- Scalar temp_value;
- const Scalar *a;
- const Scalar *b;
- if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
- Scalar::e_void) {
- if (!b->IsZero() && GetCategory(result.m_type) == Category::Integral) {
- if (IsSigned(result.m_type))
- result.m_integer = a->m_integer.srem(b->m_integer);
- else
- result.m_integer = a->m_integer.urem(b->m_integer);
+ if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
+ if (!rhs.IsZero() && result.m_type == Scalar::e_int) {
+ result.m_integer = lhs.m_integer % rhs.m_integer;
return result;
}
}
@@ -964,15 +604,11 @@ const Scalar lldb_private::operator%(const Scalar &lhs, const Scalar &rhs) {
return result;
}
-const Scalar lldb_private::operator^(const Scalar &lhs, const Scalar &rhs) {
+const Scalar lldb_private::operator^(Scalar lhs, Scalar rhs) {
Scalar result;
- Scalar temp_value;
- const Scalar *a;
- const Scalar *b;
- if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
- Scalar::e_void) {
- if (GetCategory(result.m_type) == Category::Integral)
- result.m_integer = a->m_integer ^ b->m_integer;
+ if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
+ if (result.m_type == Scalar::e_int)
+ result.m_integer = lhs.m_integer ^ rhs.m_integer;
else
result.m_type = Scalar::e_void;
}
@@ -1028,30 +664,24 @@ Status Scalar::SetValueFromCString(const char *value_str, Encoding encoding,
value_str, byte_size);
break;
}
- m_type = GetBestTypeForBitSize(8 * byte_size, is_signed);
- if (m_type == e_void) {
- error.SetErrorStringWithFormatv("unsupported integer byte size: {0}",
- byte_size);
- break;
- }
- if (is_signed)
- m_integer = integer.sextOrTrunc(GetBitSize(m_type));
- else
- m_integer = integer.zextOrTrunc(GetBitSize(m_type));
+ m_type = e_int;
+ m_integer =
+ APSInt(std::move(integer), !is_signed).extOrTrunc(8 * byte_size);
break;
}
case eEncodingIEEE754: {
- Type type = GetValueTypeForFloatWithByteSize(byte_size);
- if (type == e_void) {
- error.SetErrorStringWithFormatv("unsupported float byte size: {0}",
- byte_size);
- break;
- }
- APFloat f(GetFltSemantics(type));
+ // FIXME: It's not possible to unambiguously map a byte size to a floating
+ // point type. This function should be refactored to take an explicit
+ // semantics argument.
+ const llvm::fltSemantics &sem =
+ byte_size <= 4 ? APFloat::IEEEsingle()
+ : byte_size <= 8 ? APFloat::IEEEdouble()
+ : APFloat::x87DoubleExtended();
+ APFloat f(sem);
if (llvm::Expected<APFloat::opStatus> op =
f.convertFromString(value_str, APFloat::rmNearestTiesToEven)) {
- m_type = type;
+ m_type = e_float;
m_float = std::move(f);
} else
error = op.takeError();
@@ -1068,12 +698,9 @@ Status Scalar::SetValueFromCString(const char *value_str, Encoding encoding,
return error;
}
-Status Scalar::SetValueFromData(DataExtractor &data, lldb::Encoding encoding,
- size_t byte_size) {
+Status Scalar::SetValueFromData(const DataExtractor &data,
+ lldb::Encoding encoding, size_t byte_size) {
Status error;
-
- type128 int128;
- type256 int256;
switch (encoding) {
case lldb::eEncodingInvalid:
error.SetErrorString("invalid encoding");
@@ -1081,100 +708,22 @@ Status Scalar::SetValueFromData(DataExtractor &data, lldb::Encoding encoding,
case lldb::eEncodingVector:
error.SetErrorString("vector encoding unsupported");
break;
- case lldb::eEncodingUint: {
- lldb::offset_t offset = 0;
-
- switch (byte_size) {
- case 1:
- operator=(data.GetU8(&offset));
- break;
- case 2:
- operator=(data.GetU16(&offset));
- break;
- case 4:
- operator=(data.GetU32(&offset));
- break;
- case 8:
- operator=(data.GetU64(&offset));
- break;
- case 16:
- if (data.GetByteOrder() == eByteOrderBig) {
- int128.x[1] = data.GetU64(&offset);
- int128.x[0] = data.GetU64(&offset);
- } else {
- int128.x[0] = data.GetU64(&offset);
- int128.x[1] = data.GetU64(&offset);
- }
- operator=(llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, int128.x));
- break;
- case 32:
- if (data.GetByteOrder() == eByteOrderBig) {
- int256.x[3] = data.GetU64(&offset);
- int256.x[2] = data.GetU64(&offset);
- int256.x[1] = data.GetU64(&offset);
- int256.x[0] = data.GetU64(&offset);
- } else {
- int256.x[0] = data.GetU64(&offset);
- int256.x[1] = data.GetU64(&offset);
- int256.x[2] = data.GetU64(&offset);
- int256.x[3] = data.GetU64(&offset);
- }
- operator=(llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, int256.x));
- break;
- default:
- error.SetErrorStringWithFormat(
- "unsupported unsigned integer byte size: %" PRIu64 "",
- static_cast<uint64_t>(byte_size));
- break;
- }
- } break;
+ case lldb::eEncodingUint:
case lldb::eEncodingSint: {
- lldb::offset_t offset = 0;
-
- switch (byte_size) {
- case 1:
- operator=(static_cast<int8_t>(data.GetU8(&offset)));
- break;
- case 2:
- operator=(static_cast<int16_t>(data.GetU16(&offset)));
- break;
- case 4:
- operator=(static_cast<int32_t>(data.GetU32(&offset)));
- break;
- case 8:
- operator=(static_cast<int64_t>(data.GetU64(&offset)));
- break;
- case 16:
- if (data.GetByteOrder() == eByteOrderBig) {
- int128.x[1] = data.GetU64(&offset);
- int128.x[0] = data.GetU64(&offset);
- } else {
- int128.x[0] = data.GetU64(&offset);
- int128.x[1] = data.GetU64(&offset);
- }
- operator=(llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, int128.x));
- break;
- case 32:
- if (data.GetByteOrder() == eByteOrderBig) {
- int256.x[3] = data.GetU64(&offset);
- int256.x[2] = data.GetU64(&offset);
- int256.x[1] = data.GetU64(&offset);
- int256.x[0] = data.GetU64(&offset);
- } else {
- int256.x[0] = data.GetU64(&offset);
- int256.x[1] = data.GetU64(&offset);
- int256.x[2] = data.GetU64(&offset);
- int256.x[3] = data.GetU64(&offset);
- }
- operator=(llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, int256.x));
- break;
- default:
- error.SetErrorStringWithFormat(
- "unsupported signed integer byte size: %" PRIu64 "",
- static_cast<uint64_t>(byte_size));
- break;
+ if (data.GetByteSize() < byte_size)
+ return Status("insufficient data");
+ m_type = e_int;
+ m_integer =
+ APSInt(APInt::getNullValue(8 * byte_size), encoding == eEncodingUint);
+ if (data.GetByteOrder() == endian::InlHostByteOrder()) {
+ llvm::LoadIntFromMemory(m_integer, data.GetDataStart(), byte_size);
+ } else {
+ std::vector<uint8_t> buffer(byte_size);
+ std::copy_n(data.GetDataStart(), byte_size, buffer.rbegin());
+ llvm::LoadIntFromMemory(m_integer, buffer.data(), byte_size);
}
- } break;
+ break;
+ }
case lldb::eEncodingIEEE754: {
lldb::offset_t offset = 0;
@@ -1200,31 +749,18 @@ bool Scalar::SignExtend(uint32_t sign_bit_pos) {
switch (m_type) {
case Scalar::e_void:
case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
return false;
- 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:
- case Scalar::e_sint256:
- case Scalar::e_uint256:
- case Scalar::e_sint512:
- case Scalar::e_uint512:
+ case Scalar::e_int:
if (max_bit_pos == sign_bit_pos)
return true;
else if (sign_bit_pos < (max_bit_pos - 1)) {
llvm::APInt sign_bit = llvm::APInt::getSignMask(sign_bit_pos + 1);
llvm::APInt bitwize_and = m_integer & sign_bit;
if (bitwize_and.getBoolValue()) {
- const llvm::APInt mask =
+ llvm::APInt mask =
~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1);
- m_integer |= mask;
+ m_integer |= APSInt(std::move(mask), m_integer.isUnsigned());
}
return true;
}
@@ -1266,64 +802,29 @@ bool Scalar::ExtractBitfield(uint32_t bit_size, uint32_t bit_offset) {
switch (m_type) {
case Scalar::e_void:
case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
break;
- case Scalar::e_sint:
- case Scalar::e_slong:
- case Scalar::e_slonglong:
- case Scalar::e_sint128:
- case Scalar::e_sint256:
- case Scalar::e_sint512:
- 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:
- case Scalar::e_uint256:
- case Scalar::e_uint512:
- m_integer = m_integer.lshr(bit_offset)
- .zextOrTrunc(bit_size)
- .zextOrSelf(8 * GetByteSize());
+ case Scalar::e_int:
+ m_integer >>= bit_offset;
+ m_integer = m_integer.extOrTrunc(bit_size).extOrTrunc(8 * GetByteSize());
return true;
}
return false;
}
-bool lldb_private::operator==(const Scalar &lhs, const Scalar &rhs) {
+bool lldb_private::operator==(Scalar lhs, Scalar rhs) {
// If either entry is void then we can just compare the types
if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
return lhs.m_type == rhs.m_type;
- Scalar temp_value;
- const Scalar *a;
- const Scalar *b;
llvm::APFloat::cmpResult result;
- switch (PromoteToMaxType(lhs, rhs, temp_value, a, b)) {
+ switch (Scalar::PromoteToMaxType(lhs, 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_uint128:
- case Scalar::e_sint256:
- case Scalar::e_uint256:
- case Scalar::e_sint512:
- case Scalar::e_uint512:
- return a->m_integer == b->m_integer;
+ case Scalar::e_int:
+ return lhs.m_integer == rhs.m_integer;
case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- result = a->m_float.compare(b->m_float);
+ result = lhs.m_float.compare(rhs.m_float);
if (result == llvm::APFloat::cmpEqual)
return true;
}
@@ -1334,35 +835,18 @@ bool lldb_private::operator!=(const Scalar &lhs, const Scalar &rhs) {
return !(lhs == rhs);
}
-bool lldb_private::operator<(const Scalar &lhs, const Scalar &rhs) {
+bool lldb_private::operator<(Scalar lhs, Scalar rhs) {
if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
return false;
- Scalar temp_value;
- const Scalar *a;
- const Scalar *b;
llvm::APFloat::cmpResult result;
- switch (PromoteToMaxType(lhs, rhs, temp_value, a, b)) {
+ switch (Scalar::PromoteToMaxType(lhs, rhs)) {
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:
- case Scalar::e_sint512:
- case Scalar::e_uint512:
- 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_int:
+ return lhs.m_integer < rhs.m_integer;
case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- result = a->m_float.compare(b->m_float);
+ result = lhs.m_float.compare(rhs.m_float);
if (result == llvm::APFloat::cmpLessThan)
return true;
}
@@ -1385,23 +869,10 @@ bool Scalar::ClearBit(uint32_t bit) {
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:
- case e_sint512:
- case e_uint512:
+ case e_int:
m_integer.clearBit(bit);
return true;
case e_float:
- case e_double:
- case e_long_double:
break;
}
return false;
@@ -1411,23 +882,10 @@ bool Scalar::SetBit(uint32_t bit) {
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:
- case e_sint512:
- case e_uint512:
+ case e_int:
m_integer.setBit(bit);
return true;
case e_float:
- case e_double:
- case e_long_double:
break;
}
return false;
diff --git a/contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp b/contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp
index cfe7577e4863..def096866426 100644
--- a/contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp
+++ b/contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp
@@ -233,6 +233,8 @@ StringExtractorGDBRemote::GetServerPacketType() const {
return eServerPacketType_qPlatform_chmod;
if (PACKET_MATCHES("qProcessInfo"))
return eServerPacketType_qProcessInfo;
+ if (PACKET_STARTS_WITH("qPathComplete:"))
+ return eServerPacketType_qPathComplete;
break;
case 'Q':
@@ -308,6 +310,8 @@ StringExtractorGDBRemote::GetServerPacketType() const {
return eServerPacketType_jTraceStart;
if (PACKET_STARTS_WITH("jTraceStop:"))
return eServerPacketType_jTraceStop;
+ if (PACKET_MATCHES("jLLDBTraceSupportedType"))
+ return eServerPacketType_jLLDBTraceSupportedType;
break;
case 'v':
diff --git a/contrib/llvm-project/lldb/source/Utility/StringLexer.cpp b/contrib/llvm-project/lldb/source/Utility/StringLexer.cpp
index 947472a014eb..26185517e275 100644
--- a/contrib/llvm-project/lldb/source/Utility/StringLexer.cpp
+++ b/contrib/llvm-project/lldb/source/Utility/StringLexer.cpp
@@ -10,10 +10,11 @@
#include <algorithm>
#include <assert.h>
+#include <utility>
using namespace lldb_private;
-StringLexer::StringLexer(std::string s) : m_data(s), m_position(0) {}
+StringLexer::StringLexer(std::string s) : m_data(std::move(s)), m_position(0) {}
StringLexer::Character StringLexer::Peek() { return m_data[m_position]; }
diff --git a/contrib/llvm-project/lldb/source/Utility/StringList.cpp b/contrib/llvm-project/lldb/source/Utility/StringList.cpp
index 809c5a02acf6..d3896ca60ac9 100644
--- a/contrib/llvm-project/lldb/source/Utility/StringList.cpp
+++ b/contrib/llvm-project/lldb/source/Utility/StringList.cpp
@@ -212,7 +212,7 @@ StringList &StringList::operator<<(const std::string &str) {
return *this;
}
-StringList &StringList::operator<<(StringList strings) {
+StringList &StringList::operator<<(const StringList &strings) {
AppendList(strings);
return *this;
}
diff --git a/contrib/llvm-project/lldb/source/Utility/StructuredData.cpp b/contrib/llvm-project/lldb/source/Utility/StructuredData.cpp
index df1b35618e4a..b349de7b0b78 100644
--- a/contrib/llvm-project/lldb/source/Utility/StructuredData.cpp
+++ b/contrib/llvm-project/lldb/source/Utility/StructuredData.cpp
@@ -21,7 +21,8 @@ static StructuredData::ObjectSP ParseJSONValue(json::Value &value);
static StructuredData::ObjectSP ParseJSONObject(json::Object *object);
static StructuredData::ObjectSP ParseJSONArray(json::Array *array);
-StructuredData::ObjectSP StructuredData::ParseJSON(std::string json_text) {
+StructuredData::ObjectSP
+StructuredData::ParseJSON(const std::string &json_text) {
llvm::Expected<json::Value> value = json::parse(json_text);
if (!value) {
llvm::consumeError(value.takeError());
@@ -41,7 +42,12 @@ StructuredData::ParseJSONFromFile(const FileSpec &input_spec, Status &error) {
buffer_or_error.getError().message());
return return_sp;
}
- return ParseJSON(buffer_or_error.get()->getBuffer().str());
+ llvm::Expected<json::Value> value =
+ json::parse(buffer_or_error.get()->getBuffer().str());
+ if (value)
+ return ParseJSONValue(*value);
+ error.SetErrorString(toString(value.takeError()));
+ return StructuredData::ObjectSP();
}
static StructuredData::ObjectSP ParseJSONValue(json::Value &value) {
@@ -51,21 +57,17 @@ static StructuredData::ObjectSP ParseJSONValue(json::Value &value) {
if (json::Array *A = value.getAsArray())
return ParseJSONArray(A);
- std::string s;
- if (json::fromJSON(value, s))
- return std::make_shared<StructuredData::String>(s);
+ if (auto s = value.getAsString())
+ return std::make_shared<StructuredData::String>(*s);
- bool b;
- if (json::fromJSON(value, b))
- return std::make_shared<StructuredData::Boolean>(b);
+ if (auto b = value.getAsBoolean())
+ return std::make_shared<StructuredData::Boolean>(*b);
- int64_t i;
- if (json::fromJSON(value, i))
- return std::make_shared<StructuredData::Integer>(i);
+ if (auto i = value.getAsInteger())
+ return std::make_shared<StructuredData::Integer>(*i);
- double d;
- if (json::fromJSON(value, d))
- return std::make_shared<StructuredData::Float>(d);
+ if (auto d = value.getAsNumber())
+ return std::make_shared<StructuredData::Float>(*d);
return StructuredData::ObjectSP();
}
diff --git a/contrib/llvm-project/lldb/source/Utility/TildeExpressionResolver.cpp b/contrib/llvm-project/lldb/source/Utility/TildeExpressionResolver.cpp
index c8a0800cb807..75d9c47e656d 100644
--- a/contrib/llvm-project/lldb/source/Utility/TildeExpressionResolver.cpp
+++ b/contrib/llvm-project/lldb/source/Utility/TildeExpressionResolver.cpp
@@ -75,9 +75,8 @@ bool StandardTildeExpressionResolver::ResolvePartial(StringRef Expr,
bool TildeExpressionResolver::ResolveFullPath(
StringRef Expr, llvm::SmallVectorImpl<char> &Output) {
- Output.clear();
if (!Expr.startswith("~")) {
- Output.append(Expr.begin(), Expr.end());
+ Output.assign(Expr.begin(), Expr.end());
return false;
}
@@ -85,8 +84,10 @@ bool TildeExpressionResolver::ResolveFullPath(
StringRef Left =
Expr.take_until([](char c) { return path::is_separator(c); });
- if (!ResolveExact(Left, Output))
+ if (!ResolveExact(Left, Output)) {
+ Output.assign(Expr.begin(), Expr.end());
return false;
+ }
Output.append(Expr.begin() + Left.size(), Expr.end());
return true;
diff --git a/contrib/llvm-project/lldb/source/Utility/Timer.cpp b/contrib/llvm-project/lldb/source/Utility/Timer.cpp
index d55c9863117b..7ead51069529 100644
--- a/contrib/llvm-project/lldb/source/Utility/Timer.cpp
+++ b/contrib/llvm-project/lldb/source/Utility/Timer.cpp
@@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//
#include "lldb/Utility/Timer.h"
#include "lldb/Utility/Stream.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Signposts.h"
#include <algorithm>
#include <map>
@@ -28,6 +30,9 @@ typedef std::vector<Timer *> TimerStack;
static std::atomic<Timer::Category *> g_categories;
} // end of anonymous namespace
+/// Allows llvm::Timer to emit signposts when supported.
+static llvm::ManagedStatic<llvm::SignpostEmitter> Signposts;
+
std::atomic<bool> Timer::g_quiet(true);
std::atomic<unsigned> Timer::g_display_depth(0);
static std::mutex &GetFileMutex() {
@@ -54,6 +59,7 @@ void Timer::SetQuiet(bool value) { g_quiet = value; }
Timer::Timer(Timer::Category &category, const char *format, ...)
: m_category(category), m_total_start(std::chrono::steady_clock::now()) {
+ Signposts->startInterval(this, m_category.GetName());
TimerStack &stack = GetTimerStackForCurrentThread();
stack.push_back(this);
@@ -80,6 +86,8 @@ Timer::~Timer() {
auto total_dur = stop_time - m_total_start;
auto timer_dur = total_dur - m_child_duration;
+ Signposts->endInterval(this, m_category.GetName());
+
TimerStack &stack = GetTimerStackForCurrentThread();
if (g_quiet && stack.size() <= g_display_depth) {
std::lock_guard<std::mutex> lock(GetFileMutex());
diff --git a/contrib/llvm-project/lldb/source/Utility/TraceOptions.cpp b/contrib/llvm-project/lldb/source/Utility/TraceOptions.cpp
new file mode 100644
index 000000000000..292fb600e6ed
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Utility/TraceOptions.cpp
@@ -0,0 +1,25 @@
+//===-- TraceOptions.cpp ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/TraceOptions.h"
+
+using namespace lldb_private;
+
+namespace llvm {
+namespace json {
+
+bool fromJSON(const Value &value, TraceTypeInfo &info, Path path) {
+ ObjectMapper o(value, path);
+ if (!o)
+ return false;
+ o.map("description", info.description);
+ return o.map("name", info.name);
+}
+
+} // namespace json
+} // namespace llvm
diff --git a/contrib/llvm-project/lldb/source/Utility/UUID.cpp b/contrib/llvm-project/lldb/source/Utility/UUID.cpp
index 4177b43de818..73088fb22db8 100644
--- a/contrib/llvm-project/lldb/source/Utility/UUID.cpp
+++ b/contrib/llvm-project/lldb/source/Utility/UUID.cpp
@@ -35,6 +35,16 @@ static inline bool separate(size_t count) {
}
}
+UUID UUID::fromCvRecord(UUID::CvRecordPdb70 debug_info) {
+ llvm::sys::swapByteOrder(debug_info.Uuid.Data1);
+ llvm::sys::swapByteOrder(debug_info.Uuid.Data2);
+ llvm::sys::swapByteOrder(debug_info.Uuid.Data3);
+ llvm::sys::swapByteOrder(debug_info.Age);
+ if (debug_info.Age)
+ return UUID::fromOptionalData(&debug_info, sizeof(debug_info));
+ return UUID::fromOptionalData(&debug_info.Uuid, sizeof(debug_info.Uuid));
+}
+
std::string UUID::GetAsString(llvm::StringRef separator) const {
std::string result;
llvm::raw_string_ostream os(result);
diff --git a/contrib/llvm-project/lldb/source/Utility/UnimplementedError.cpp b/contrib/llvm-project/lldb/source/Utility/UnimplementedError.cpp
new file mode 100644
index 000000000000..034ad5b17b64
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Utility/UnimplementedError.cpp
@@ -0,0 +1,11 @@
+//===-- UnimplementedError.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/UnimplementedError.h"
+
+char lldb_private::UnimplementedError::ID;
diff --git a/contrib/llvm-project/lldb/source/Utility/XcodeSDK.cpp b/contrib/llvm-project/lldb/source/Utility/XcodeSDK.cpp
index 066bf457966c..4f64042e3643 100644
--- a/contrib/llvm-project/lldb/source/Utility/XcodeSDK.cpp
+++ b/contrib/llvm-project/lldb/source/Utility/XcodeSDK.cpp
@@ -54,12 +54,12 @@ XcodeSDK::XcodeSDK(XcodeSDK::Info info) : m_name(GetName(info.type).str()) {
}
}
-XcodeSDK &XcodeSDK::operator=(XcodeSDK other) {
+XcodeSDK &XcodeSDK::operator=(const XcodeSDK &other) {
m_name = other.m_name;
return *this;
}
-bool XcodeSDK::operator==(XcodeSDK other) {
+bool XcodeSDK::operator==(const XcodeSDK &other) {
return m_name == other.m_name;
}
@@ -147,7 +147,7 @@ bool XcodeSDK::Info::operator==(const Info &other) const {
std::tie(other.type, other.version, other.internal);
}
-void XcodeSDK::Merge(XcodeSDK other) {
+void XcodeSDK::Merge(const XcodeSDK &other) {
// The "bigger" SDK always wins.
auto l = Parse();
auto r = other.Parse();
diff --git a/contrib/llvm-project/lldb/source/lldb.cpp b/contrib/llvm-project/lldb/source/lldb.cpp
index 6d4ed66074dc..10fc2d7cf556 100644
--- a/contrib/llvm-project/lldb/source/lldb.cpp
+++ b/contrib/llvm-project/lldb/source/lldb.cpp
@@ -13,9 +13,7 @@ using namespace lldb_private;
#include "clang/Basic/Version.h"
-#ifdef HAVE_VCS_VERSION_INC
#include "VCSVersion.inc"
-#endif
static const char *GetLLDBRevision() {
#ifdef LLDB_REVISION
@@ -33,12 +31,7 @@ static const char *GetLLDBRepository() {
#endif
}
-#define QUOTE(str) #str
-#define EXPAND_AND_QUOTE(str) QUOTE(str)
-
const char *lldb_private::GetVersion() {
- // On platforms other than Darwin, report a version number in the same style
- // as the clang tool.
static std::string g_version_str;
if (g_version_str.empty()) {
g_version_str += "lldb version ";
diff --git a/contrib/llvm-project/lldb/tools/driver/Driver.cpp b/contrib/llvm-project/lldb/tools/driver/Driver.cpp
index cea9e5a44aa8..210a712f9741 100644
--- a/contrib/llvm-project/lldb/tools/driver/Driver.cpp
+++ b/contrib/llvm-project/lldb/tools/driver/Driver.cpp
@@ -112,7 +112,10 @@ Driver::Driver()
g_driver = this;
}
-Driver::~Driver() { g_driver = nullptr; }
+Driver::~Driver() {
+ SBDebugger::Destroy(m_debugger);
+ g_driver = nullptr;
+}
void Driver::OptionData::AddInitialCommand(std::string command,
CommandPlacement placement,
@@ -491,9 +494,9 @@ int Driver::MainLoop() {
SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
// Before we handle any options from the command line, we parse the
- // .lldbinit file in the user's home directory.
+ // REPL init file or the default file in the user's home directory.
SBCommandReturnObject result;
- sb_interpreter.SourceInitFileInHomeDirectory(result);
+ sb_interpreter.SourceInitFileInHomeDirectory(result, m_option_data.m_repl);
if (m_option_data.m_debug_mode) {
result.PutError(m_debugger.GetErrorFile());
result.PutOutput(m_debugger.GetOutputFile());
@@ -590,7 +593,7 @@ int Driver::MainLoop() {
if (commands_file == nullptr) {
// We should have already printed an error in PrepareCommandsForSourcing.
- exit(1);
+ return 1;
}
m_debugger.SetInputFileHandle(commands_file, true);
@@ -618,7 +621,7 @@ int Driver::MainLoop() {
// non-zero exit status.
if (m_option_data.m_batch &&
results.GetResult() == lldb::eCommandInterpreterResultCommandError)
- exit(1);
+ return 1;
if (m_option_data.m_batch &&
results.GetResult() == lldb::eCommandInterpreterResultInferiorCrash &&
@@ -643,7 +646,7 @@ int Driver::MainLoop() {
if (m_option_data.m_batch &&
local_results.GetResult() ==
lldb::eCommandInterpreterResultCommandError)
- exit(1);
+ return 1;
}
}
m_debugger.SetAsync(old_async);
@@ -676,9 +679,7 @@ int Driver::MainLoop() {
reset_stdin_termios();
fclose(stdin);
- int exit_code = sb_interpreter.GetQuitStatus();
- SBDebugger::Destroy(m_debugger);
- return exit_code;
+ return sb_interpreter.GetQuitStatus();
}
void Driver::ResizeWindow(unsigned short col) {
@@ -729,25 +730,11 @@ void sigcont_handler(int signo) {
signal(signo, sigcont_handler);
}
-void reproducer_handler(void *argv0) {
+void reproducer_handler(void *finalize_cmd) {
if (SBReproducer::Generate()) {
- auto exe = static_cast<const char *>(argv0);
- llvm::outs() << "********************\n";
- llvm::outs() << "Crash reproducer for ";
- llvm::outs() << lldb::SBDebugger::GetVersionString() << '\n';
- llvm::outs() << '\n';
- llvm::outs() << "Reproducer written to '" << SBReproducer::GetPath()
- << "'\n";
- llvm::outs() << '\n';
- llvm::outs() << "Before attaching the reproducer to a bug report:\n";
- llvm::outs() << " - Look at the directory to ensure you're willing to "
- "share its content.\n";
- llvm::outs()
- << " - Make sure the reproducer works by replaying the reproducer.\n";
- llvm::outs() << '\n';
- llvm::outs() << "Replay the reproducer with the following command:\n";
- llvm::outs() << exe << " -replay " << SBReproducer::GetPath() << "\n";
- llvm::outs() << "********************\n";
+ int result = std::system(static_cast<const char *>(finalize_cmd));
+ (void)result;
+ fflush(stdout);
}
}
@@ -764,11 +751,11 @@ EXAMPLES:
arguments passed to the debugged executable, arguments starting with a - must
be passed after --.
- lldb --arch x86_64 /path/to/program program argument -- --arch arvm7
+ lldb --arch x86_64 /path/to/program program argument -- --arch armv7
For convenience, passing the executable after -- is also supported.
- lldb --arch x86_64 -- /path/to/program program argument --arch arvm7
+ lldb --arch x86_64 -- /path/to/program program argument --arch armv7
Passing one of the attach options causes lldb to immediately attach to the
given process.
@@ -799,10 +786,37 @@ EXAMPLES:
llvm::Optional<int> InitializeReproducer(llvm::StringRef argv0,
opt::InputArgList &input_args) {
+ if (auto *finalize_path = input_args.getLastArg(OPT_reproducer_finalize)) {
+ if (const char *error = SBReproducer::Finalize(finalize_path->getValue())) {
+ WithColor::error() << "reproducer finalization failed: " << error << '\n';
+ return 1;
+ }
+
+ llvm::outs() << "********************\n";
+ llvm::outs() << "Crash reproducer for ";
+ llvm::outs() << lldb::SBDebugger::GetVersionString() << '\n';
+ llvm::outs() << '\n';
+ llvm::outs() << "Reproducer written to '" << SBReproducer::GetPath()
+ << "'\n";
+ llvm::outs() << '\n';
+ llvm::outs() << "Before attaching the reproducer to a bug report:\n";
+ llvm::outs() << " - Look at the directory to ensure you're willing to "
+ "share its content.\n";
+ llvm::outs()
+ << " - Make sure the reproducer works by replaying the reproducer.\n";
+ llvm::outs() << '\n';
+ llvm::outs() << "Replay the reproducer with the following command:\n";
+ llvm::outs() << argv0 << " -replay " << finalize_path->getValue() << "\n";
+ llvm::outs() << "********************\n";
+ return 0;
+ }
+
if (auto *replay_path = input_args.getLastArg(OPT_replay)) {
- const bool no_version_check = input_args.hasArg(OPT_no_version_check);
+ SBReplayOptions replay_options;
+ replay_options.SetCheckVersion(!input_args.hasArg(OPT_no_version_check));
+ replay_options.SetVerify(!input_args.hasArg(OPT_no_verification));
if (const char *error =
- SBReproducer::Replay(replay_path->getValue(), no_version_check)) {
+ SBReproducer::Replay(replay_path->getValue(), replay_options)) {
WithColor::error() << "reproducer replay failed: " << error << '\n';
return 1;
}
@@ -819,12 +833,6 @@ llvm::Optional<int> InitializeReproducer(llvm::StringRef argv0,
}
if (capture || capture_path) {
- // Register the reproducer signal handler.
- if (!input_args.hasArg(OPT_no_generate_on_signal)) {
- llvm::sys::AddSignalHandler(reproducer_handler,
- const_cast<char *>(argv0.data()));
- }
-
if (capture_path) {
if (!capture)
WithColor::warning() << "-capture-path specified without -capture\n";
@@ -841,6 +849,19 @@ llvm::Optional<int> InitializeReproducer(llvm::StringRef argv0,
}
if (generate_on_exit)
SBReproducer::SetAutoGenerate(true);
+
+ // Register the reproducer signal handler.
+ if (!input_args.hasArg(OPT_no_generate_on_signal)) {
+ if (const char *reproducer_path = SBReproducer::GetPath()) {
+ // Leaking the string on purpose.
+ std::string *finalize_cmd = new std::string(argv0);
+ finalize_cmd->append(" --reproducer-finalize '");
+ finalize_cmd->append(reproducer_path);
+ finalize_cmd->append("'");
+ llvm::sys::AddSignalHandler(reproducer_handler,
+ const_cast<char *>(finalize_cmd->c_str()));
+ }
+ }
}
return llvm::None;
@@ -853,10 +874,11 @@ int main(int argc, char const *argv[]) {
// Parse arguments.
LLDBOptTable T;
- unsigned MAI;
- unsigned MAC;
+ unsigned MissingArgIndex;
+ unsigned MissingArgCount;
ArrayRef<const char *> arg_arr = makeArrayRef(argv + 1, argc - 1);
- opt::InputArgList input_args = T.ParseArgs(arg_arr, MAI, MAC);
+ opt::InputArgList input_args =
+ T.ParseArgs(arg_arr, MissingArgIndex, MissingArgCount);
llvm::StringRef argv0 = llvm::sys::path::filename(argv[0]);
if (input_args.hasArg(OPT_help)) {
@@ -864,11 +886,19 @@ int main(int argc, char const *argv[]) {
return 0;
}
+ // Check for missing argument error.
+ if (MissingArgCount) {
+ WithColor::error() << "argument to '"
+ << input_args.getArgString(MissingArgIndex)
+ << "' is missing\n";
+ }
// Error out on unknown options.
if (input_args.hasArg(OPT_UNKNOWN)) {
for (auto *arg : input_args.filtered(OPT_UNKNOWN)) {
WithColor::error() << "unknown option: " << arg->getSpelling() << '\n';
}
+ }
+ if (MissingArgCount || input_args.hasArg(OPT_UNKNOWN)) {
llvm::errs() << "Use '" << argv0
<< " --help' for a complete list of options.\n";
return 1;
diff --git a/contrib/llvm-project/lldb/tools/driver/Options.td b/contrib/llvm-project/lldb/tools/driver/Options.td
index 96f696ec3ca6..8bcb0e7bc52e 100644
--- a/contrib/llvm-project/lldb/tools/driver/Options.td
+++ b/contrib/llvm-project/lldb/tools/driver/Options.td
@@ -232,8 +232,12 @@ def capture_path: Separate<["--", "-"], "capture-path">,
def replay: Separate<["--", "-"], "replay">,
MetaVarName<"<filename>">,
HelpText<"Tells the debugger to replay a reproducer from <filename>.">;
+def reproducer_finalize: Separate<["--", "-"], "reproducer-finalize">,
+ MetaVarName<"<filename>">;
def no_version_check: F<"reproducer-no-version-check">,
HelpText<"Disable the reproducer version check.">;
+def no_verification: F<"reproducer-no-verify">,
+ HelpText<"Disable the reproducer verification.">;
def no_generate_on_signal: F<"reproducer-no-generate-on-signal">,
HelpText<"Don't generate reproducer when a signal is received.">;
def generate_on_exit: F<"reproducer-generate-on-exit">,
diff --git a/contrib/llvm-project/lldb/tools/lldb-server/LLGSOptions.td b/contrib/llvm-project/lldb/tools/lldb-server/LLGSOptions.td
new file mode 100644
index 000000000000..429a4671764f
--- /dev/null
+++ b/contrib/llvm-project/lldb/tools/lldb-server/LLGSOptions.td
@@ -0,0 +1,62 @@
+include "llvm/Option/OptParser.td"
+
+class F<string name>: Flag<["--", "-"], name>;
+class R<list<string> prefixes, string name>
+ : Option<prefixes, name, KIND_REMAINING_ARGS>;
+
+multiclass SJ<string name, string help> {
+ def NAME: Separate<["--", "-"], name>,
+ HelpText<help>;
+ def NAME # _eq: Joined<["--", "-"], name # "=">,
+ Alias<!cast<Separate>(NAME)>;
+}
+
+def grp_connect : OptionGroup<"connection">, HelpText<"CONNECTION">;
+
+defm fd: SJ<"fd", "Communicate over the given file descriptor.">,
+ MetaVarName<"<fd>">,
+ Group<grp_connect>;
+
+defm named_pipe: SJ<"named-pipe", "Write port lldb-server will listen on to the given named pipe.">,
+ MetaVarName<"<name>">,
+ Group<grp_connect>;
+
+defm pipe: SJ<"pipe", "Write port lldb-server will listen on to the given file descriptor.">,
+ MetaVarName<"<fd>">,
+ Group<grp_connect>;
+
+def reverse_connect: F<"reverse-connect">,
+ HelpText<"Connect to the client instead of passively waiting for a connection. In this case [host]:port denotes the remote address to connect to.">,
+ Group<grp_connect>;
+
+def grp_general : OptionGroup<"general options">, HelpText<"GENERAL OPTIONS">;
+
+defm log_channels: SJ<"log-channels", "Channels to log. A colon-separated list of entries. Each entry starts with a channel followed by a space-separated list of categories.">,
+ MetaVarName<"<channel1 categories...:channel2 categories...>">,
+ Group<grp_general>;
+
+defm log_file: SJ<"log-file", "Destination file to log to. If empty, log to stderr.">,
+ MetaVarName<"<file>">,
+ Group<grp_general>;
+
+def setsid: F<"setsid">, HelpText<"Run lldb-server in a new session.">,
+ Group<grp_general>;
+def: Flag<["-"], "S">, Alias<setsid>,
+ Group<grp_general>;
+
+def help: F<"help">, HelpText<"Prints out the usage information for lldb-server.">,
+ Group<grp_general>;
+def: Flag<["-"], "h">, Alias<help>,
+ Group<grp_general>;
+
+def grp_target : OptionGroup<"target selection">, HelpText<"TARGET SELECTION">;
+
+defm attach: SJ<"attach", "Attach to the process given by a (numeric) process id or a name.">,
+ MetaVarName<"<pid-or-name>">,
+ Group<grp_target>;
+
+def REM : R<["--"], "">, HelpText<"Launch program for debugging.">,
+ MetaVarName<"program args">,
+ Group<grp_target>;
+
+def: F<"native-regs">; // Noop. Present for backwards compatibility only.
diff --git a/contrib/llvm-project/lldb/tools/lldb-server/lldb-gdbserver.cpp b/contrib/llvm-project/lldb/tools/lldb-server/lldb-gdbserver.cpp
index 5f06503d6424..a9db73f90098 100644
--- a/contrib/llvm-project/lldb/tools/lldb-server/lldb-gdbserver.cpp
+++ b/contrib/llvm-project/lldb/tools/lldb-server/lldb-gdbserver.cpp
@@ -17,7 +17,6 @@
#include <unistd.h>
#endif
-
#include "Acceptor.h"
#include "LLDBServerUtilities.h"
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h"
@@ -25,8 +24,6 @@
#include "lldb/Host/Config.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/HostGetOpt.h"
-#include "lldb/Host/OptionParser.h"
#include "lldb/Host/Pipe.h"
#include "lldb/Host/Socket.h"
#include "lldb/Host/StringConvert.h"
@@ -34,10 +31,16 @@
#include "lldb/Target/Process.h"
#include "lldb/Utility/Status.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/OptTable.h"
+#include "llvm/Option/Option.h"
#include "llvm/Support/Errno.h"
+#include "llvm/Support/WithColor.h"
#if defined(__linux__)
#include "Plugins/Process/Linux/NativeProcessLinux.h"
+#elif defined(__FreeBSD__)
+#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"
#elif defined(__NetBSD__)
#include "Plugins/Process/NetBSD/NativeProcessNetBSD.h"
#elif defined(_WIN32)
@@ -61,6 +64,8 @@ using namespace lldb_private::process_gdb_remote;
namespace {
#if defined(__linux__)
typedef process_linux::NativeProcessLinux::Factory NativeProcessFactory;
+#elif defined(__FreeBSD__)
+typedef process_freebsd::NativeProcessFreeBSD::Factory NativeProcessFactory;
#elif defined(__NetBSD__)
typedef process_netbsd::NativeProcessNetBSD::Factory NativeProcessFactory;
#elif defined(_WIN32)
@@ -84,31 +89,6 @@ public:
#endif
}
-// option descriptors for getopt_long_only()
-
-static int g_debug = 0;
-static int g_verbose = 0;
-
-static struct option g_long_options[] = {
- {"debug", no_argument, &g_debug, 1},
- {"verbose", no_argument, &g_verbose, 1},
- {"log-file", required_argument, nullptr, 'l'},
- {"log-channels", required_argument, nullptr, 'c'},
- {"attach", required_argument, nullptr, 'a'},
- {"named-pipe", required_argument, nullptr, 'N'},
- {"pipe", required_argument, nullptr, 'U'},
- {"native-regs", no_argument, nullptr,
- 'r'}, // Specify to use the native registers instead of the gdb defaults
- // for the architecture. NOTE: this is a do-nothing arg as it's
- // behavior is default now. FIXME remove call from lldb-platform.
- {"reverse-connect", no_argument, nullptr,
- 'R'}, // Specifies that llgs attaches to the client address:port rather
- // than llgs listening for a connection from address on port.
- {"setsid", no_argument, nullptr,
- 'S'}, // Call setsid() to make llgs run in its own session.
- {"fd", required_argument, nullptr, 'F'},
- {nullptr, 0, nullptr, 0}};
-
#ifndef _WIN32
// Watch for signals
static int g_sighup_received_count = 0;
@@ -125,20 +105,6 @@ static void sighup_handler(MainLoopBase &mainloop) {
}
#endif // #ifndef _WIN32
-static void display_usage(const char *progname, const char *subcommand) {
- fprintf(stderr, "Usage:\n %s %s "
- "[--log-file log-file-name] "
- "[--log-channels log-channel-list] "
- "[--setsid] "
- "[--fd file-descriptor]"
- "[--named-pipe named-pipe-path] "
- "[--native-regs] "
- "[--attach pid] "
- "[[HOST]:PORT] "
- "[-- PROGRAM ARG1 ARG2 ...]\n",
- progname, subcommand);
-}
-
void handle_attach_to_pid(GDBRemoteCommunicationServerLLGS &gdb_server,
lldb::pid_t pid) {
Status error = gdb_server.AttachToProcess(pid);
@@ -172,12 +138,12 @@ void handle_attach(GDBRemoteCommunicationServerLLGS &gdb_server,
handle_attach_to_process_name(gdb_server, attach_target);
}
-void handle_launch(GDBRemoteCommunicationServerLLGS &gdb_server, int argc,
- const char *const argv[]) {
+void handle_launch(GDBRemoteCommunicationServerLLGS &gdb_server,
+ llvm::ArrayRef<llvm::StringRef> Arguments) {
ProcessLaunchInfo info;
info.GetFlags().Set(eLaunchFlagStopAtEntry | eLaunchFlagDebug |
eLaunchFlagDisableASLR);
- info.SetArguments(const_cast<const char **>(argv), true);
+ info.SetArguments(Args(Arguments), true);
llvm::SmallString<64> cwd;
if (std::error_code ec = llvm::sys::fs::current_path(cwd)) {
@@ -194,7 +160,7 @@ void handle_launch(GDBRemoteCommunicationServerLLGS &gdb_server, int argc,
Status error = gdb_server.LaunchProcess();
if (error.Fail()) {
llvm::errs() << llvm::formatv("error: failed to launch '{0}': {1}\n",
- argv[0], error);
+ Arguments[0], error);
exit(1);
}
}
@@ -225,7 +191,7 @@ Status writeSocketIdToPipe(lldb::pipe_t unnamed_pipe,
void ConnectToRemote(MainLoop &mainloop,
GDBRemoteCommunicationServerLLGS &gdb_server,
- bool reverse_connect, const char *const host_and_port,
+ bool reverse_connect, llvm::StringRef host_and_port,
const char *const progname, const char *const subcommand,
const char *const named_pipe_path, pipe_t unnamed_pipe,
int connection_fd) {
@@ -254,7 +220,7 @@ void ConnectToRemote(MainLoop &mainloop,
connection_url, error.AsCString());
exit(-1);
}
- } else if (host_and_port && host_and_port[0]) {
+ } else if (!host_and_port.empty()) {
// Parse out host and port.
std::string final_host_and_port;
std::string connection_host;
@@ -265,9 +231,10 @@ void ConnectToRemote(MainLoop &mainloop,
// expect the remainder to be the port.
if (host_and_port[0] == ':')
final_host_and_port.append("localhost");
- final_host_and_port.append(host_and_port);
+ final_host_and_port.append(host_and_port.str());
- const std::string::size_type colon_pos = final_host_and_port.find(':');
+ // Note: use rfind, because the host/port may look like "[::1]:12345".
+ const std::string::size_type colon_pos = final_host_and_port.rfind(':');
if (colon_pos != std::string::npos) {
connection_host = final_host_and_port.substr(0, colon_pos);
connection_port = final_host_and_port.substr(colon_pos + 1);
@@ -356,7 +323,57 @@ void ConnectToRemote(MainLoop &mainloop,
printf("Connection established.\n");
}
-// main
+namespace {
+enum ID {
+ OPT_INVALID = 0, // This is not an option ID.
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ OPT_##ID,
+#include "LLGSOptions.inc"
+#undef OPTION
+};
+
+#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
+#include "LLGSOptions.inc"
+#undef PREFIX
+
+const opt::OptTable::Info InfoTable[] = {
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ { \
+ PREFIX, NAME, HELPTEXT, \
+ METAVAR, OPT_##ID, opt::Option::KIND##Class, \
+ PARAM, FLAGS, OPT_##GROUP, \
+ OPT_##ALIAS, ALIASARGS, VALUES},
+#include "LLGSOptions.inc"
+#undef OPTION
+};
+
+class LLGSOptTable : public opt::OptTable {
+public:
+ LLGSOptTable() : OptTable(InfoTable) {}
+
+ void PrintHelp(llvm::StringRef Name) {
+ std::string Usage =
+ (Name + " [options] [[host]:port] [[--] program args...]").str();
+ OptTable::PrintHelp(llvm::outs(), Usage.c_str(), "lldb-server");
+ llvm::outs() << R"(
+DESCRIPTION
+ lldb-server connects to the LLDB client, which drives the debugging session.
+ If no connection options are given, the [host]:port argument must be present
+ and will denote the address that lldb-server will listen on. [host] defaults
+ to "localhost" if empty. Port can be zero, in which case the port number will
+ be chosen dynamically and written to destinations given by --named-pipe and
+ --pipe arguments.
+
+ If no target is selected at startup, lldb-server can be directed by the LLDB
+ client to launch or attach to a process.
+
+)";
+ }
+};
+} // namespace
+
int main_gdbserver(int argc, char *argv[]) {
Status error;
MainLoop mainloop;
@@ -369,10 +386,6 @@ int main_gdbserver(int argc, char *argv[]) {
const char *progname = argv[0];
const char *subcommand = argv[1];
- argc--;
- argv++;
- int long_option_index = 0;
- int ch;
std::string attach_target;
std::string named_pipe_path;
std::string log_file;
@@ -385,94 +398,71 @@ int main_gdbserver(int argc, char *argv[]) {
// ProcessLaunchInfo launch_info;
ProcessAttachInfo attach_info;
- bool show_usage = false;
- int option_error = 0;
-#if __GLIBC__
- optind = 0;
-#else
- optreset = 1;
- optind = 1;
-#endif
-
- std::string short_options(OptionParser::GetShortOptionString(g_long_options));
-
- while ((ch = getopt_long_only(argc, argv, short_options.c_str(),
- g_long_options, &long_option_index)) != -1) {
- switch (ch) {
- case 0: // Any optional that auto set themselves will return 0
- break;
-
- case 'l': // Set Log File
- if (optarg && optarg[0])
- log_file.assign(optarg);
- break;
-
- case 'c': // Log Channels
- if (optarg && optarg[0])
- log_channels = StringRef(optarg);
- break;
-
- case 'N': // named pipe
- if (optarg && optarg[0])
- named_pipe_path = optarg;
- break;
-
- case 'U': // unnamed pipe
- if (optarg && optarg[0])
- unnamed_pipe = (pipe_t)StringConvert::ToUInt64(optarg, -1);
- break;
-
- case 'r':
- // Do nothing, native regs is the default these days
- break;
-
- case 'R':
- reverse_connect = true;
- break;
+ LLGSOptTable Opts;
+ llvm::BumpPtrAllocator Alloc;
+ llvm::StringSaver Saver(Alloc);
+ bool HasError = false;
+ opt::InputArgList Args = Opts.parseArgs(argc - 1, argv + 1, OPT_UNKNOWN,
+ Saver, [&](llvm::StringRef Msg) {
+ WithColor::error() << Msg << "\n";
+ HasError = true;
+ });
+ std::string Name =
+ (llvm::sys::path::filename(argv[0]) + " g[dbserver]").str();
+ std::string HelpText =
+ "Use '" + Name + " --help' for a complete list of options.\n";
+ if (HasError) {
+ llvm::errs() << HelpText;
+ return 1;
+ }
- case 'F':
- connection_fd = StringConvert::ToUInt32(optarg, -1);
- break;
+ if (Args.hasArg(OPT_help)) {
+ Opts.PrintHelp(Name);
+ return 0;
+ }
#ifndef _WIN32
- case 'S':
- // Put llgs into a new session. Terminals group processes
- // into sessions and when a special terminal key sequences
- // (like control+c) are typed they can cause signals to go out to
- // all processes in a session. Using this --setsid (-S) option
- // will cause debugserver to run in its own sessions and be free
- // from such issues.
- //
- // This is useful when llgs is spawned from a command
- // line application that uses llgs to do the debugging,
- // yet that application doesn't want llgs receiving the
- // signals sent to the session (i.e. dying when anyone hits ^C).
- {
- const ::pid_t new_sid = setsid();
- if (new_sid == -1) {
- llvm::errs() << llvm::formatv(
- "failed to set new session id for {0} ({1})\n", LLGS_PROGRAM_NAME,
- llvm::sys::StrError());
- }
+ if (Args.hasArg(OPT_setsid)) {
+ // Put llgs into a new session. Terminals group processes
+ // into sessions and when a special terminal key sequences
+ // (like control+c) are typed they can cause signals to go out to
+ // all processes in a session. Using this --setsid (-S) option
+ // will cause debugserver to run in its own sessions and be free
+ // from such issues.
+ //
+ // This is useful when llgs is spawned from a command
+ // line application that uses llgs to do the debugging,
+ // yet that application doesn't want llgs receiving the
+ // signals sent to the session (i.e. dying when anyone hits ^C).
+ {
+ const ::pid_t new_sid = setsid();
+ if (new_sid == -1) {
+ WithColor::warning()
+ << llvm::formatv("failed to set new session id for {0} ({1})\n",
+ LLGS_PROGRAM_NAME, llvm::sys::StrError());
}
- break;
+ }
+ }
#endif
- case 'a': // attach {pid|process_name}
- if (optarg && optarg[0])
- attach_target = optarg;
- break;
-
- case 'h': /* fall-through is intentional */
- case '?':
- show_usage = true;
- break;
+ log_file = Args.getLastArgValue(OPT_log_file).str();
+ log_channels = Args.getLastArgValue(OPT_log_channels);
+ named_pipe_path = Args.getLastArgValue(OPT_named_pipe).str();
+ reverse_connect = Args.hasArg(OPT_reverse_connect);
+ attach_target = Args.getLastArgValue(OPT_attach).str();
+ if (Args.hasArg(OPT_pipe)) {
+ uint64_t Arg;
+ if (!llvm::to_integer(Args.getLastArgValue(OPT_pipe), Arg)) {
+ WithColor::error() << "invalid '--pipe' argument\n" << HelpText;
+ return 1;
}
+ unnamed_pipe = (pipe_t)Arg;
}
-
- if (show_usage || option_error) {
- display_usage(progname, subcommand);
- exit(option_error);
+ if (Args.hasArg(OPT_fd)) {
+ if (!llvm::to_integer(Args.getLastArgValue(OPT_fd), connection_fd)) {
+ WithColor::error() << "invalid '--fd' argument\n" << HelpText;
+ return 1;
+ }
}
if (!LLDBServerUtilities::SetupLogging(
@@ -481,30 +471,26 @@ int main_gdbserver(int argc, char *argv[]) {
LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION))
return -1;
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(GDBR_LOG_PROCESS));
- if (log) {
- LLDB_LOGF(log, "lldb-server launch");
- for (int i = 0; i < argc; i++) {
- LLDB_LOGF(log, "argv[%i] = '%s'", i, argv[i]);
- }
+ std::vector<llvm::StringRef> Inputs;
+ for (opt::Arg *Arg : Args.filtered(OPT_INPUT))
+ Inputs.push_back(Arg->getValue());
+ if (opt::Arg *Arg = Args.getLastArg(OPT_REM)) {
+ for (const char *Val : Arg->getValues())
+ Inputs.push_back(Val);
}
-
- // Skip any options we consumed with getopt_long_only.
- argc -= optind;
- argv += optind;
-
- if (argc == 0 && connection_fd == -1) {
- fputs("No arguments\n", stderr);
- display_usage(progname, subcommand);
- exit(255);
+ if (Inputs.empty() && connection_fd == -1) {
+ WithColor::error() << "no connection arguments\n" << HelpText;
+ return 1;
}
NativeProcessFactory factory;
GDBRemoteCommunicationServerLLGS gdb_server(mainloop, factory);
- const char *const host_and_port = argv[0];
- argc -= 1;
- argv += 1;
+ llvm::StringRef host_and_port;
+ if (!Inputs.empty()) {
+ host_and_port = Inputs.front();
+ Inputs.erase(Inputs.begin());
+ }
// Any arguments left over are for the program that we need to launch. If
// there
@@ -515,8 +501,8 @@ int main_gdbserver(int argc, char *argv[]) {
// explicitly asked to attach with the --attach={pid|program_name} form.
if (!attach_target.empty())
handle_attach(gdb_server, attach_target);
- else if (argc > 0)
- handle_launch(gdb_server, argc, argv);
+ else if (!Inputs.empty())
+ handle_launch(gdb_server, Inputs);
// Print version info.
printf("%s-%s\n", LLGS_PROGRAM_NAME, LLGS_VERSION_STR);
@@ -527,7 +513,6 @@ int main_gdbserver(int argc, char *argv[]) {
if (!gdb_server.IsConnected()) {
fprintf(stderr, "no connection information provided, unable to run\n");
- display_usage(progname, subcommand);
return 1;
}
diff --git a/contrib/llvm-project/lldb/tools/lldb-server/lldb-platform.cpp b/contrib/llvm-project/lldb/tools/lldb-server/lldb-platform.cpp
index 33f918ffc2a1..a5d4ecfa3f29 100644
--- a/contrib/llvm-project/lldb/tools/lldb-server/lldb-platform.cpp
+++ b/contrib/llvm-project/lldb/tools/lldb-server/lldb-platform.cpp
@@ -104,11 +104,12 @@ static Status save_socket_id_to_file(const std::string &socket_id,
llvm::SmallString<64> temp_file_path;
temp_file_spec.AppendPathComponent("port-file.%%%%%%");
+ temp_file_path = temp_file_spec.GetPath();
Status status;
if (auto Err =
handleErrors(llvm::writeFileAtomically(
- temp_file_path, temp_file_spec.GetPath(), socket_id),
+ temp_file_path, file_spec.GetPath(), socket_id),
[&status, &file_spec](const AtomicFileWriteError &E) {
std::string ErrorMsgBuffer;
llvm::raw_string_ostream S(ErrorMsgBuffer);
@@ -230,7 +231,7 @@ int main_platform(int argc, char *argv[]) {
break;
}
if (ch == 'P')
- gdbserver_portmap[portnum] = LLDB_INVALID_PROCESS_ID;
+ gdbserver_portmap.AllowPort(portnum);
else if (ch == 'm')
min_gdbserver_port = portnum;
else
@@ -249,8 +250,8 @@ int main_platform(int argc, char *argv[]) {
// Make a port map for a port range that was specified.
if (min_gdbserver_port && min_gdbserver_port < max_gdbserver_port) {
- for (uint16_t port = min_gdbserver_port; port < max_gdbserver_port; ++port)
- gdbserver_portmap[port] = LLDB_INVALID_PROCESS_ID;
+ gdbserver_portmap = GDBRemoteCommunicationServerPlatform::PortMap(
+ min_gdbserver_port, max_gdbserver_port);
} else if (min_gdbserver_port || max_gdbserver_port) {
fprintf(stderr, "error: --min-gdbserver-port (%u) is not lower than "
"--max-gdbserver-port (%u)\n",
@@ -348,13 +349,13 @@ int main_platform(int argc, char *argv[]) {
if (platform.IsConnected()) {
if (inferior_arguments.GetArgumentCount() > 0) {
lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
- uint16_t port = 0;
+ llvm::Optional<uint16_t> port = 0;
std::string socket_name;
Status error = platform.LaunchGDBServer(inferior_arguments,
"", // hostname
pid, port, socket_name);
if (error.Success())
- platform.SetPendingGdbServer(pid, port, socket_name);
+ platform.SetPendingGdbServer(pid, *port, socket_name);
else
fprintf(stderr, "failed to start gdbserver: %s\n", error.AsCString());
}