aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2015-02-09 01:44:09 +0000
committerEd Maste <emaste@FreeBSD.org>2015-02-09 01:44:09 +0000
commit12bd4897ff0678fa663e09d78ebc22dd255ceb86 (patch)
treea8f4b3abea3e6937e60728991c736e6e3d322fc1
parent205afe679855a4ce8149cdaa94d3f0868ce796dc (diff)
downloadsrc-12bd4897ff0678fa663e09d78ebc22dd255ceb86.tar.gz
src-12bd4897ff0678fa663e09d78ebc22dd255ceb86.zip
Import LLDB as of upstream SVN 228549 (git 39760838)vendor/lldb/lldb-r228549
Notes
Notes: svn path=/vendor/lldb/dist/; revision=278425 svn path=/vendor/lldb/lldb-r228549/; revision=278426; tag=vendor/lldb/lldb-r228549
-rw-r--r--include/lldb/API/SBLaunchInfo.h186
-rw-r--r--include/lldb/API/SBPlatform.h13
-rw-r--r--include/lldb/API/SBTarget.h161
-rw-r--r--include/lldb/API/SBType.h6
-rw-r--r--include/lldb/Breakpoint/Breakpoint.h18
-rw-r--r--include/lldb/Breakpoint/BreakpointLocation.h4
-rw-r--r--include/lldb/Breakpoint/StoppointLocation.h3
-rw-r--r--include/lldb/Core/ArchSpec.h15
-rw-r--r--include/lldb/Core/Broadcaster.h7
-rw-r--r--include/lldb/Core/Connection.h22
-rw-r--r--include/lldb/Core/ConnectionMachPort.h4
-rw-r--r--include/lldb/Core/ConnectionSharedMemory.h3
-rw-r--r--include/lldb/Core/Debugger.h26
-rw-r--r--include/lldb/Core/Disassembler.h6
-rw-r--r--include/lldb/Core/FormatEntity.h260
-rw-r--r--include/lldb/Core/Mangled.h19
-rw-r--r--include/lldb/Core/Module.h16
-rw-r--r--include/lldb/Core/RegularExpression.h41
-rw-r--r--include/lldb/Core/ValueObject.h12
-rw-r--r--include/lldb/Core/ValueObjectSyntheticFilter.h3
-rw-r--r--include/lldb/DataFormatters/TypeSummary.h28
-rw-r--r--include/lldb/Expression/ASTResultSynthesizer.h2
-rw-r--r--include/lldb/Expression/ASTStructExtractor.h2
-rw-r--r--include/lldb/Expression/IRExecutionUnit.h10
-rw-r--r--include/lldb/Host/File.h3
-rw-r--r--include/lldb/Host/Host.h3
-rw-r--r--include/lldb/Host/PipeBase.h2
-rw-r--r--include/lldb/Host/Socket.h31
-rw-r--r--include/lldb/Host/SocketAddress.h7
-rw-r--r--include/lldb/Host/StringConvert.h45
-rw-r--r--include/lldb/Host/common/NativeBreakpoint.h (renamed from source/Host/common/NativeBreakpoint.h)0
-rw-r--r--include/lldb/Host/common/NativeBreakpointList.h (renamed from source/Host/common/NativeBreakpointList.h)0
-rw-r--r--include/lldb/Host/common/NativeProcessProtocol.h (renamed from source/Host/common/NativeProcessProtocol.h)5
-rw-r--r--include/lldb/Host/common/NativeRegisterContext.h (renamed from include/lldb/Target/NativeRegisterContext.h)7
-rw-r--r--include/lldb/Host/common/NativeRegisterContextRegisterInfo.h (renamed from include/lldb/Target/NativeRegisterContextRegisterInfo.h)3
-rw-r--r--include/lldb/Host/common/NativeThreadProtocol.h (renamed from source/Host/common/NativeThreadProtocol.h)5
-rw-r--r--include/lldb/Host/common/NativeWatchpointList.h47
-rw-r--r--include/lldb/Host/common/SoftwareBreakpoint.h (renamed from source/Host/common/SoftwareBreakpoint.h)0
-rw-r--r--include/lldb/Host/posix/ConnectionFileDescriptorPosix.h6
-rw-r--r--include/lldb/Host/posix/PipePosix.h2
-rw-r--r--include/lldb/Interpreter/Args.h12
-rw-r--r--include/lldb/Interpreter/CommandInterpreter.h9
-rw-r--r--include/lldb/Interpreter/OptionGroupPlatform.h6
-rw-r--r--include/lldb/Interpreter/OptionValue.h15
-rw-r--r--include/lldb/Interpreter/OptionValueFormatEntity.h107
-rw-r--r--include/lldb/Interpreter/OptionValueProperties.h4
-rw-r--r--include/lldb/Interpreter/OptionValueRegex.h8
-rw-r--r--include/lldb/Interpreter/OptionValues.h1
-rw-r--r--include/lldb/Interpreter/ScriptInterpreter.h16
-rw-r--r--include/lldb/Interpreter/ScriptInterpreterPython.h194
-rw-r--r--include/lldb/Symbol/ClangASTType.h8
-rw-r--r--include/lldb/Symbol/ObjectFile.h17
-rw-r--r--include/lldb/Symbol/SymbolContext.h1
-rw-r--r--include/lldb/Target/FileAction.h2
-rw-r--r--include/lldb/Target/LanguageRuntime.h7
-rw-r--r--include/lldb/Target/ObjCLanguageRuntime.h7
-rw-r--r--include/lldb/Target/Platform.h30
-rw-r--r--include/lldb/Target/Process.h6
-rw-r--r--include/lldb/Utility/AnsiTerminal.h31
-rw-r--r--include/lldb/Utility/ProcessStructReader.h4
-rw-r--r--include/lldb/lldb-enumerations.h11
-rw-r--r--include/lldb/lldb-forward.h1
-rw-r--r--source/API/SBInstruction.cpp10
-rw-r--r--source/API/SBInstructionList.cpp5
-rw-r--r--source/API/SBLaunchInfo.cpp278
-rw-r--r--source/API/SBPlatform.cpp157
-rw-r--r--source/API/SBStream.cpp6
-rw-r--r--source/API/SBTarget.cpp256
-rw-r--r--source/API/SBThread.cpp3
-rw-r--r--source/API/SBType.cpp25
-rw-r--r--source/API/SBTypeCategory.cpp4
-rw-r--r--source/API/SBValue.cpp3
-rw-r--r--source/Breakpoint/Breakpoint.cpp8
-rw-r--r--source/Breakpoint/BreakpointLocation.cpp15
-rw-r--r--source/Breakpoint/StoppointLocation.cpp7
-rw-r--r--source/Commands/CommandObjectBreakpoint.cpp20
-rw-r--r--source/Commands/CommandObjectDisassemble.cpp6
-rw-r--r--source/Commands/CommandObjectExpression.cpp4
-rw-r--r--source/Commands/CommandObjectFrame.cpp5
-rw-r--r--source/Commands/CommandObjectGUI.cpp20
-rw-r--r--source/Commands/CommandObjectHelp.cpp20
-rw-r--r--source/Commands/CommandObjectHelp.h11
-rw-r--r--source/Commands/CommandObjectLog.cpp3
-rw-r--r--source/Commands/CommandObjectMemory.cpp21
-rw-r--r--source/Commands/CommandObjectPlatform.cpp42
-rw-r--r--source/Commands/CommandObjectProcess.cpp201
-rw-r--r--source/Commands/CommandObjectSource.cpp8
-rw-r--r--source/Commands/CommandObjectTarget.cpp141
-rw-r--r--source/Commands/CommandObjectThread.cpp113
-rw-r--r--source/Commands/CommandObjectWatchpoint.cpp3
-rw-r--r--source/Core/Address.cpp4
-rw-r--r--source/Core/ArchSpec.cpp13
-rw-r--r--source/Core/Broadcaster.cpp10
-rw-r--r--source/Core/ConnectionMachPort.cpp8
-rw-r--r--source/Core/ConnectionSharedMemory.cpp7
-rw-r--r--source/Core/ConstString.cpp2
-rw-r--r--source/Core/Debugger.cpp1750
-rw-r--r--source/Core/Disassembler.cpp45
-rw-r--r--source/Core/Error.cpp2
-rw-r--r--source/Core/FormatEntity.cpp2511
-rw-r--r--source/Core/IOHandler.cpp28
-rw-r--r--source/Core/Log.cpp4
-rw-r--r--source/Core/Mangled.cpp44
-rw-r--r--source/Core/Module.cpp25
-rw-r--r--source/Core/RegisterValue.cpp5
-rw-r--r--source/Core/RegularExpression.cpp56
-rw-r--r--source/Core/Scalar.cpp5
-rw-r--r--source/Core/StreamFile.cpp3
-rw-r--r--source/Core/Value.cpp4
-rw-r--r--source/Core/ValueObject.cpp75
-rw-r--r--source/Core/ValueObjectConstResult.cpp4
-rw-r--r--source/Core/ValueObjectDynamicValue.cpp2
-rw-r--r--source/Core/ValueObjectMemory.cpp2
-rw-r--r--source/Core/ValueObjectSyntheticFilter.cpp6
-rw-r--r--source/Core/ValueObjectVariable.cpp4
-rw-r--r--source/DataFormatters/CXXFormatterFunctions.cpp2
-rw-r--r--source/DataFormatters/FormatManager.cpp2
-rw-r--r--source/DataFormatters/LibCxx.cpp5
-rw-r--r--source/DataFormatters/LibCxxInitializerList.cpp2
-rw-r--r--source/DataFormatters/LibCxxVector.cpp2
-rw-r--r--source/DataFormatters/TypeSummary.cpp36
-rw-r--r--source/DataFormatters/TypeSynthetic.cpp24
-rw-r--r--source/Expression/ASTResultSynthesizer.cpp4
-rw-r--r--source/Expression/ASTStructExtractor.cpp4
-rw-r--r--source/Expression/ClangExpressionParser.cpp1
-rw-r--r--source/Expression/ClangModulesDeclVendor.cpp8
-rw-r--r--source/Expression/ExpressionSourceCode.cpp6
-rw-r--r--source/Expression/IRExecutionUnit.cpp165
-rw-r--r--source/Expression/IRForTarget.cpp6
-rw-r--r--source/Expression/Materializer.cpp4
-rw-r--r--source/Host/common/Editline.cpp21
-rw-r--r--source/Host/common/File.cpp9
-rw-r--r--source/Host/common/FileSpec.cpp11
-rw-r--r--source/Host/common/Host.cpp21
-rw-r--r--source/Host/common/HostInfoBase.cpp269
-rw-r--r--source/Host/common/NativeBreakpoint.cpp2
-rw-r--r--source/Host/common/NativeBreakpointList.cpp6
-rw-r--r--source/Host/common/NativeProcessProtocol.cpp30
-rw-r--r--source/Host/common/NativeRegisterContext.cpp (renamed from source/Target/NativeRegisterContext.cpp)12
-rw-r--r--source/Host/common/NativeRegisterContextRegisterInfo.cpp (renamed from source/Target/NativeRegisterContextRegisterInfo.cpp)8
-rw-r--r--source/Host/common/NativeThreadProtocol.cpp30
-rw-r--r--source/Host/common/NativeWatchpointList.cpp35
-rw-r--r--source/Host/common/Socket.cpp70
-rw-r--r--source/Host/common/SocketAddress.cpp72
-rw-r--r--source/Host/common/SoftwareBreakpoint.cpp4
-rw-r--r--source/Host/common/StringConvert.cpp93
-rw-r--r--source/Host/common/ThreadLauncher.cpp10
-rw-r--r--source/Host/posix/ConnectionFileDescriptorPosix.cpp53
-rw-r--r--source/Host/posix/PipePosix.cpp35
-rw-r--r--source/Interpreter/Args.cpp96
-rw-r--r--source/Interpreter/CommandHistory.cpp8
-rw-r--r--source/Interpreter/CommandInterpreter.cpp166
-rw-r--r--source/Interpreter/CommandObjectRegexCommand.cpp2
-rw-r--r--source/Interpreter/OptionGroupPlatform.cpp35
-rw-r--r--source/Interpreter/OptionGroupValueObjectDisplay.cpp7
-rw-r--r--source/Interpreter/OptionValue.cpp45
-rw-r--r--source/Interpreter/OptionValueArray.cpp9
-rw-r--r--source/Interpreter/OptionValueFileSpecLIst.cpp7
-rw-r--r--source/Interpreter/OptionValueFormatEntity.cpp124
-rw-r--r--source/Interpreter/OptionValuePathMappings.cpp7
-rw-r--r--source/Interpreter/OptionValueProperties.cpp12
-rw-r--r--source/Interpreter/OptionValueRegex.cpp4
-rw-r--r--source/Interpreter/OptionValueSInt64.cpp4
-rw-r--r--source/Interpreter/OptionValueUInt64.cpp4
-rw-r--r--source/Interpreter/Property.cpp41
-rw-r--r--source/Interpreter/ScriptInterpreterPython.cpp59
-rw-r--r--source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp6
-rw-r--r--source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp10
-rw-r--r--source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp21
-rw-r--r--source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp20
-rw-r--r--source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp20
-rw-r--r--source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp27
-rw-r--r--source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp4
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp32
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h3
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp3
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp3
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.cpp84
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp146
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h6
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.cpp183
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.h15
-rw-r--r--source/Plugins/Process/POSIX/CrashReason.cpp315
-rw-r--r--source/Plugins/Process/POSIX/CrashReason.h62
-rw-r--r--source/Plugins/Process/POSIX/POSIXStopInfo.cpp15
-rw-r--r--source/Plugins/Process/POSIX/POSIXStopInfo.h22
-rw-r--r--source/Plugins/Process/POSIX/ProcessMessage.cpp190
-rw-r--r--source/Plugins/Process/POSIX/ProcessMessage.h51
-rw-r--r--source/Plugins/Process/POSIX/ProcessPOSIX.cpp11
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp53
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h9
-rw-r--r--source/Plugins/Process/Utility/DynamicRegisterInfo.cpp6
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp39
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.cpp7
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp5
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_i386.h3
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp24
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp51
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h45
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_powerpc.h79
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoInterface.h11
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_powerpc.h42
-rw-r--r--source/Plugins/Process/Utility/lldb-x86-register-enums.h6
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.cpp6
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp29
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h11
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.cpp5
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.h2
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp49
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h13
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp86
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h32
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp420
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h8
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp62
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp7
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp32
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp147
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h7
-rw-r--r--source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp6
-rw-r--r--source/Symbol/ClangASTContext.cpp4
-rw-r--r--source/Symbol/ClangASTType.cpp106
-rw-r--r--source/Symbol/CompactUnwindInfo.cpp29
-rw-r--r--source/Symbol/SymbolContext.cpp68
-rw-r--r--source/Symbol/Type.cpp16
-rw-r--r--source/Symbol/Variable.cpp3
-rw-r--r--source/Target/ExecutionContext.cpp6
-rw-r--r--source/Target/LanguageRuntime.cpp3
-rw-r--r--source/Target/ObjCLanguageRuntime.cpp46
-rw-r--r--source/Target/Platform.cpp85
-rw-r--r--source/Target/Process.cpp10
-rw-r--r--source/Target/ProcessLaunchInfo.cpp9
-rw-r--r--source/Target/StackFrame.cpp5
-rw-r--r--source/Target/StopInfo.cpp5
-rw-r--r--source/Target/TargetList.cpp48
-rw-r--r--source/Target/Thread.cpp23
-rw-r--r--source/Target/ThreadPlanTracer.cpp2
-rw-r--r--source/Target/UnixSignals.cpp4
-rw-r--r--source/Utility/StringExtractorGDBRemote.cpp3
-rw-r--r--source/Utility/StringExtractorGDBRemote.h1
-rw-r--r--source/Utility/UriParser.cpp21
-rw-r--r--source/Utility/UriParser.h8
-rw-r--r--tools/compact-unwind/compact-unwind-dumper.c50
-rw-r--r--tools/lldb-mi/Driver.cpp22
-rw-r--r--tools/lldb-mi/Driver.h10
-rw-r--r--tools/lldb-mi/MICmdArgValConsume.cpp29
-rw-r--r--tools/lldb-mi/MICmdCmd.h4
-rw-r--r--tools/lldb-mi/MICmdCmdBreak.cpp45
-rw-r--r--tools/lldb-mi/MICmdCmdBreak.h2
-rw-r--r--tools/lldb-mi/MICmdCmdData.cpp257
-rw-r--r--tools/lldb-mi/MICmdCmdData.h7
-rw-r--r--tools/lldb-mi/MICmdCmdExec.cpp49
-rw-r--r--tools/lldb-mi/MICmdCmdExec.h2
-rw-r--r--tools/lldb-mi/MICmdCmdFile.cpp6
-rw-r--r--tools/lldb-mi/MICmdCmdGdbInfo.cpp10
-rw-r--r--tools/lldb-mi/MICmdCmdMiscellanous.cpp34
-rw-r--r--tools/lldb-mi/MICmdCmdMiscellanous.h2
-rw-r--r--tools/lldb-mi/MICmdCmdStack.cpp103
-rw-r--r--tools/lldb-mi/MICmdCmdStack.h10
-rw-r--r--tools/lldb-mi/MICmdCmdTarget.cpp21
-rw-r--r--tools/lldb-mi/MICmdCmdThread.cpp14
-rw-r--r--tools/lldb-mi/MICmdCmdVar.cpp129
-rw-r--r--tools/lldb-mi/MICmdCmdVar.h7
-rw-r--r--tools/lldb-mi/MICmnLLDBBroadcaster.h2
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp377
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfo.h43
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h2
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugger.cpp19
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugger.h6
-rw-r--r--tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp87
-rw-r--r--tools/lldb-mi/MICmnLLDBProxySBValue.cpp6
-rw-r--r--tools/lldb-mi/MICmnLLDBProxySBValue.h2
-rw-r--r--tools/lldb-mi/MICmnLLDBUtilSBValue.cpp2
-rw-r--r--tools/lldb-mi/MICmnLLDBUtilSBValue.h2
-rw-r--r--tools/lldb-mi/MICmnLog.cpp1
-rw-r--r--tools/lldb-mi/MICmnResources.cpp3
-rw-r--r--tools/lldb-mi/MICmnResources.h3
-rw-r--r--tools/lldb-mi/MIDriver.cpp11
-rw-r--r--tools/lldb-mi/MIDriverBase.cpp4
-rw-r--r--tools/lldb-mi/MIDriverBase.h4
-rw-r--r--tools/lldb-mi/MIDriverMain.cpp14
-rw-r--r--tools/lldb-mi/MIDriverMgr.cpp20
-rw-r--r--tools/lldb-mi/MIDriverMgr.h2
-rw-r--r--tools/lldb-mi/MIReadMe.txt2
285 files changed, 8898 insertions, 4823 deletions
diff --git a/include/lldb/API/SBLaunchInfo.h b/include/lldb/API/SBLaunchInfo.h
new file mode 100644
index 000000000000..a5921ab90d48
--- /dev/null
+++ b/include/lldb/API/SBLaunchInfo.h
@@ -0,0 +1,186 @@
+//===-- SBLaunchInfo.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBLaunchInfo_h_
+#define LLDB_SBLaunchInfo_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBPlatform;
+class SBTarget;
+
+class SBLaunchInfo
+{
+public:
+ SBLaunchInfo (const char **argv);
+
+ ~SBLaunchInfo();
+
+ lldb::pid_t
+ GetProcessID();
+
+ uint32_t
+ GetUserID();
+
+ uint32_t
+ GetGroupID();
+
+ bool
+ UserIDIsValid ();
+
+ bool
+ GroupIDIsValid ();
+
+ void
+ SetUserID (uint32_t uid);
+
+ void
+ SetGroupID (uint32_t gid);
+
+ SBFileSpec
+ GetExecutableFile ();
+
+ //----------------------------------------------------------------------
+ /// Set the executable file that will be used to launch the process and
+ /// optionally set it as the first argument in the argument vector.
+ ///
+ /// This only needs to be specified if clients wish to carefully control
+ /// the exact path will be used to launch a binary. If you create a
+ /// target with a symlink, that symlink will get resolved in the target
+ /// and the resolved path will get used to launch the process. Calling
+ /// this function can help you still launch your process using the
+ /// path of your choice.
+ ///
+ /// If this function is not called prior to launching with
+ /// SBTarget::Launch(...), the target will use the resolved executable
+ /// path that was used to create the target.
+ ///
+ /// @param[in] exe_file
+ /// The override path to use when launching the executable.
+ ///
+ /// @param[in] add_as_first_arg
+ /// If true, then the path will be inserted into the argument vector
+ /// prior to launching. Otherwise the argument vector will be left
+ /// alone.
+ //----------------------------------------------------------------------
+ void
+ SetExecutableFile (SBFileSpec exe_file, bool add_as_first_arg);
+
+
+ //----------------------------------------------------------------------
+ /// Get the listener that will be used to receive process events.
+ ///
+ /// If no listener has been set via a call to
+ /// SBLaunchInfo::SetListener(), then an invalid SBListener will be
+ /// returned (SBListener::IsValid() will return false). If a listener
+ /// has been set, then the valid listener object will be returned.
+ //----------------------------------------------------------------------
+ SBListener
+ GetListener ();
+
+ //----------------------------------------------------------------------
+ /// Set the listener that will be used to receive process events.
+ ///
+ /// By default the SBDebugger, which has a listener, that the SBTarget
+ /// belongs to will listen for the process events. Calling this function
+ /// allows a different listener to be used to listen for process events.
+ //----------------------------------------------------------------------
+ void
+ SetListener (SBListener &listener);
+
+ uint32_t
+ GetNumArguments ();
+
+ const char *
+ GetArgumentAtIndex (uint32_t idx);
+
+ void
+ SetArguments (const char **argv, bool append);
+
+ uint32_t
+ GetNumEnvironmentEntries ();
+
+ const char *
+ GetEnvironmentEntryAtIndex (uint32_t idx);
+
+ void
+ SetEnvironmentEntries (const char **envp, bool append);
+
+ void
+ Clear ();
+
+ const char *
+ GetWorkingDirectory () const;
+
+ void
+ SetWorkingDirectory (const char *working_dir);
+
+ uint32_t
+ GetLaunchFlags ();
+
+ void
+ SetLaunchFlags (uint32_t flags);
+
+ const char *
+ GetProcessPluginName ();
+
+ void
+ SetProcessPluginName (const char *plugin_name);
+
+ const char *
+ GetShell ();
+
+ void
+ SetShell (const char * path);
+
+ uint32_t
+ GetResumeCount ();
+
+ void
+ SetResumeCount (uint32_t c);
+
+ bool
+ AddCloseFileAction (int fd);
+
+ bool
+ AddDuplicateFileAction (int fd, int dup_fd);
+
+ bool
+ AddOpenFileAction (int fd, const char *path, bool read, bool write);
+
+ bool
+ AddSuppressFileAction (int fd, bool read, bool write);
+
+ void
+ SetLaunchEventData (const char *data);
+
+ const char *
+ GetLaunchEventData () const;
+
+ bool
+ GetDetachOnError() const;
+
+ void
+ SetDetachOnError(bool enable);
+
+protected:
+ friend class SBPlatform;
+ friend class SBTarget;
+
+ lldb_private::ProcessLaunchInfo &
+ ref ();
+
+ ProcessLaunchInfoSP m_opaque_sp;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBLaunchInfo_h_
diff --git a/include/lldb/API/SBPlatform.h b/include/lldb/API/SBPlatform.h
index 16a546d81f9b..42b2d0492895 100644
--- a/include/lldb/API/SBPlatform.h
+++ b/include/lldb/API/SBPlatform.h
@@ -12,11 +12,15 @@
#include "lldb/API/SBDefines.h"
+#include <functional>
+
struct PlatformConnectOptions;
struct PlatformShellCommand;
namespace lldb {
+ class SBLaunchInfo;
+
class SBPlatformConnectOptions
{
public:
@@ -171,6 +175,12 @@ namespace lldb {
Run (SBPlatformShellCommand &shell_command);
SBError
+ Launch (SBLaunchInfo &launch_info);
+
+ SBError
+ Kill (const lldb::pid_t pid);
+
+ SBError
MakeDirectory (const char *path, uint32_t file_permissions = eFilePermissionsDirectoryDefault);
uint32_t
@@ -190,6 +200,9 @@ namespace lldb {
void
SetSP (const lldb::PlatformSP& platform_sp);
+ SBError
+ ExecuteConnected (const std::function<lldb_private::Error(const lldb::PlatformSP&)>& func);
+
lldb::PlatformSP m_opaque_sp;
};
diff --git a/include/lldb/API/SBTarget.h b/include/lldb/API/SBTarget.h
index a628467caa43..322cf04159ff 100644
--- a/include/lldb/API/SBTarget.h
+++ b/include/lldb/API/SBTarget.h
@@ -15,6 +15,7 @@
#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBFileSpecList.h"
+#include "lldb/API/SBLaunchInfo.h"
#include "lldb/API/SBSymbolContextList.h"
#include "lldb/API/SBType.h"
#include "lldb/API/SBValue.h"
@@ -24,166 +25,6 @@ namespace lldb {
class SBPlatform;
-class SBLaunchInfo
-{
-public:
- SBLaunchInfo (const char **argv);
-
- ~SBLaunchInfo();
-
- uint32_t
- GetUserID();
-
- uint32_t
- GetGroupID();
-
- bool
- UserIDIsValid ();
-
- bool
- GroupIDIsValid ();
-
- void
- SetUserID (uint32_t uid);
-
- void
- SetGroupID (uint32_t gid);
-
- SBFileSpec
- GetExecutableFile ();
-
- //----------------------------------------------------------------------
- /// Set the executable file that will be used to launch the process and
- /// optionally set it as the first argument in the argument vector.
- ///
- /// This only needs to be specified if clients wish to carefully control
- /// the exact path will be used to launch a binary. If you create a
- /// target with a symlink, that symlink will get resolved in the target
- /// and the resolved path will get used to launch the process. Calling
- /// this function can help you still launch your process using the
- /// path of your choice.
- ///
- /// If this function is not called prior to launching with
- /// SBTarget::Launch(...), the target will use the resolved executable
- /// path that was used to create the target.
- ///
- /// @param[in] exe_file
- /// The override path to use when launching the executable.
- ///
- /// @param[in] add_as_first_arg
- /// If true, then the path will be inserted into the argument vector
- /// prior to launching. Otherwise the argument vector will be left
- /// alone.
- //----------------------------------------------------------------------
- void
- SetExecutableFile (SBFileSpec exe_file, bool add_as_first_arg);
-
-
- //----------------------------------------------------------------------
- /// Get the listener that will be used to receive process events.
- ///
- /// If no listener has been set via a call to
- /// SBLaunchInfo::SetListener(), then an invalid SBListener will be
- /// returned (SBListener::IsValid() will return false). If a listener
- /// has been set, then the valid listener object will be returned.
- //----------------------------------------------------------------------
- SBListener
- GetListener ();
-
- //----------------------------------------------------------------------
- /// Set the listener that will be used to receive process events.
- ///
- /// By default the SBDebugger, which has a listener, that the SBTarget
- /// belongs to will listen for the process events. Calling this function
- /// allows a different listener to be used to listen for process events.
- //----------------------------------------------------------------------
- void
- SetListener (SBListener &listener);
-
- uint32_t
- GetNumArguments ();
-
- const char *
- GetArgumentAtIndex (uint32_t idx);
-
- void
- SetArguments (const char **argv, bool append);
-
- uint32_t
- GetNumEnvironmentEntries ();
-
- const char *
- GetEnvironmentEntryAtIndex (uint32_t idx);
-
- void
- SetEnvironmentEntries (const char **envp, bool append);
-
- void
- Clear ();
-
- const char *
- GetWorkingDirectory () const;
-
- void
- SetWorkingDirectory (const char *working_dir);
-
- uint32_t
- GetLaunchFlags ();
-
- void
- SetLaunchFlags (uint32_t flags);
-
- const char *
- GetProcessPluginName ();
-
- void
- SetProcessPluginName (const char *plugin_name);
-
- const char *
- GetShell ();
-
- void
- SetShell (const char * path);
-
- uint32_t
- GetResumeCount ();
-
- void
- SetResumeCount (uint32_t c);
-
- bool
- AddCloseFileAction (int fd);
-
- bool
- AddDuplicateFileAction (int fd, int dup_fd);
-
- bool
- AddOpenFileAction (int fd, const char *path, bool read, bool write);
-
- bool
- AddSuppressFileAction (int fd, bool read, bool write);
-
- void
- SetLaunchEventData (const char *data);
-
- const char *
- GetLaunchEventData () const;
-
- bool
- GetDetachOnError() const;
-
- void
- SetDetachOnError(bool enable);
-
-protected:
- friend class SBTarget;
-
- lldb_private::ProcessLaunchInfo &
- ref ();
-
- ProcessLaunchInfoSP m_opaque_sp;
-};
-
class SBAttachInfo
{
public:
diff --git a/include/lldb/API/SBType.h b/include/lldb/API/SBType.h
index 303ddff6dc09..7990fc0696a9 100644
--- a/include/lldb/API/SBType.h
+++ b/include/lldb/API/SBType.h
@@ -153,6 +153,9 @@ public:
IsArrayType ();
bool
+ IsVectorType ();
+
+ bool
IsTypedefType ();
lldb::SBType
@@ -175,6 +178,9 @@ public:
lldb::SBType
GetArrayElementType ();
+
+ lldb::SBType
+ GetVectorElementType ();
lldb::SBType
GetCanonicalType();
diff --git a/include/lldb/Breakpoint/Breakpoint.h b/include/lldb/Breakpoint/Breakpoint.h
index 61acc061aebc..883571a3ce9a 100644
--- a/include/lldb/Breakpoint/Breakpoint.h
+++ b/include/lldb/Breakpoint/Breakpoint.h
@@ -714,6 +714,19 @@ protected:
bool
IgnoreCountShouldStop ();
+ void
+ IncrementHitCount()
+ {
+ m_hit_count++;
+ }
+
+ void
+ DecrementHitCount()
+ {
+ assert (m_hit_count > 0);
+ m_hit_count--;
+ }
+
private:
// This one should only be used by Target to copy breakpoints from target to target - primarily from the dummy
// target to prime new targets.
@@ -733,7 +746,10 @@ private:
BreakpointLocationList 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.
+
void
SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind);
diff --git a/include/lldb/Breakpoint/BreakpointLocation.h b/include/lldb/Breakpoint/BreakpointLocation.h
index 8d5ebce411df..642256386785 100644
--- a/include/lldb/Breakpoint/BreakpointLocation.h
+++ b/include/lldb/Breakpoint/BreakpointLocation.h
@@ -390,6 +390,7 @@ protected:
friend class BreakpointSite;
friend class BreakpointLocationList;
friend class Process;
+ friend class StopInfoBreakpoint;
//------------------------------------------------------------------
/// Set the breakpoint site for this location to \a bp_site_sp.
@@ -417,6 +418,9 @@ private:
void
BumpHitCount();
+ void
+ UndoBumpHitCount();
+
//------------------------------------------------------------------
// Constructors and Destructors
diff --git a/include/lldb/Breakpoint/StoppointLocation.h b/include/lldb/Breakpoint/StoppointLocation.h
index 452c6388c82d..32a1dbd4386e 100644
--- a/include/lldb/Breakpoint/StoppointLocation.h
+++ b/include/lldb/Breakpoint/StoppointLocation.h
@@ -134,6 +134,9 @@ protected:
++m_hit_count;
}
+ void
+ DecrementHitCount ();
+
private:
//------------------------------------------------------------------
// For StoppointLocation only
diff --git a/include/lldb/Core/ArchSpec.h b/include/lldb/Core/ArchSpec.h
index 694e204cdc0d..93630f043822 100644
--- a/include/lldb/Core/ArchSpec.h
+++ b/include/lldb/Core/ArchSpec.h
@@ -277,6 +277,21 @@ public:
}
//------------------------------------------------------------------
+ /// Merges fields from another ArchSpec into this ArchSpec.
+ ///
+ /// This will use the supplied ArchSpec to fill in any fields of
+ /// the triple in this ArchSpec which were unspecified. This can
+ /// be used to refine a generic ArchSpec with a more specific one.
+ /// For example, if this ArchSpec's triple is something like
+ /// i386-unknown-unknown-unknown, and we have a triple which is
+ /// x64-pc-windows-msvc, then merging that triple into this one
+ /// will result in the triple i386-pc-windows-msvc.
+ ///
+ //------------------------------------------------------------------
+ void
+ MergeFrom(const ArchSpec &other);
+
+ //------------------------------------------------------------------
/// Sets this ArchSpec according to the given architecture name.
///
/// The architecture name can be one of the generic system default
diff --git a/include/lldb/Core/Broadcaster.h b/include/lldb/Core/Broadcaster.h
index 64b12ca8a938..6d54b1b43133 100644
--- a/include/lldb/Core/Broadcaster.h
+++ b/include/lldb/Core/Broadcaster.h
@@ -419,12 +419,7 @@ public:
HijackBroadcaster (Listener *listener, uint32_t event_mask = UINT32_MAX);
bool
- IsHijackedForEvent (uint32_t event_mask)
- {
- if (m_hijacking_listeners.size() > 0)
- return (event_mask & m_hijacking_masks.back()) != 0;
- return false;
- }
+ IsHijackedForEvent (uint32_t event_mask);
//------------------------------------------------------------------
/// Restore the state of the Broadcaster from a previous hijack attempt.
diff --git a/include/lldb/Core/Connection.h b/include/lldb/Core/Connection.h
index 775e0c846f85..a7b911ac382f 100644
--- a/include/lldb/Core/Connection.h
+++ b/include/lldb/Core/Connection.h
@@ -12,6 +12,7 @@
// C Includes
// C++ Includes
+#include <string>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
@@ -133,13 +134,13 @@ public:
///
/// Subclasses must override this function.
///
- /// @param[in] src
- /// A source buffer that must be at least \a src_len bytes
+ /// @param[in] dst
+ /// A desination buffer that must be at least \a dst_len bytes
/// long.
///
- /// @param[in] src_len
+ /// @param[in] dst_len
/// The number of bytes to attempt to write, and also the
- /// number of bytes are currently available in \a src.
+ /// number of bytes are currently available in \a dst.
///
/// @param[out] error_ptr
/// A pointer to an error object that should be given an
@@ -150,7 +151,18 @@ public:
/// The number of bytes actually Written.
//------------------------------------------------------------------
virtual size_t
- Write (const void *buffer, size_t length, lldb::ConnectionStatus &status, Error *error_ptr) = 0;
+ Write (const void *dst, size_t dst_len, lldb::ConnectionStatus &status, Error *error_ptr) = 0;
+
+ //------------------------------------------------------------------
+ /// Returns a URI that describes this connection object
+ ///
+ /// Subclasses may override this function.
+ ///
+ /// @return
+ /// Returns URI or an empty string if disconnecteds
+ //------------------------------------------------------------------
+ virtual std::string
+ GetURI() = 0;
private:
//------------------------------------------------------------------
diff --git a/include/lldb/Core/ConnectionMachPort.h b/include/lldb/Core/ConnectionMachPort.h
index 04ec7f69136b..78eb78cb95f4 100644
--- a/include/lldb/Core/ConnectionMachPort.h
+++ b/include/lldb/Core/ConnectionMachPort.h
@@ -56,6 +56,9 @@ public:
lldb::ConnectionStatus &status,
lldb_private::Error *error_ptr);
+ virtual std::string
+ GetURI();
+
lldb::ConnectionStatus
BootstrapCheckIn (const char *port_name,
lldb_private::Error *error_ptr);
@@ -83,6 +86,7 @@ protected:
mach_port_t m_port;
private:
+ std::string m_uri;
DISALLOW_COPY_AND_ASSIGN (ConnectionMachPort);
diff --git a/include/lldb/Core/ConnectionSharedMemory.h b/include/lldb/Core/ConnectionSharedMemory.h
index 0f9cdcb8a92d..48e62142954e 100644
--- a/include/lldb/Core/ConnectionSharedMemory.h
+++ b/include/lldb/Core/ConnectionSharedMemory.h
@@ -53,6 +53,9 @@ public:
virtual size_t
Write (const void *src, size_t src_len, lldb::ConnectionStatus &status, Error *error_ptr);
+ virtual std::string
+ GetURI();
+
lldb::ConnectionStatus
Open (bool create, const char *name, size_t size, Error *error_ptr);
diff --git a/include/lldb/Core/Debugger.h b/include/lldb/Core/Debugger.h
index 15c832f4bf66..9a3f9736fdca 100644
--- a/include/lldb/Core/Debugger.h
+++ b/include/lldb/Core/Debugger.h
@@ -19,6 +19,7 @@
#include "lldb/lldb-public.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/Communication.h"
+#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/Core/Listener.h"
#include "lldb/Core/SourceManager.h"
@@ -158,8 +159,6 @@ public:
// To get the target's source manager, call GetSourceManager on the target instead.
SourceManager &
GetSourceManager ();
-
-public:
lldb::TargetSP
GetSelectedTarget ()
@@ -224,6 +223,12 @@ public:
ConstString
GetTopIOHandlerControlSequence(char ch);
+ const char *
+ GetIOHandlerCommandPrefix();
+
+ const char *
+ GetIOHandlerHelpPrologue();
+
bool
HideTopIOHandler();
@@ -243,15 +248,7 @@ public:
GetDebuggerAtIndex (size_t index);
static bool
- FormatPrompt (const char *format,
- const SymbolContext *sc,
- const ExecutionContext *exe_ctx,
- const Address *addr,
- Stream &s,
- ValueObject* valobj = NULL);
-
- static bool
- FormatDisassemblerAddress (const char *format,
+ FormatDisassemblerAddress (const FormatEntity::Entry *format,
const SymbolContext *sc,
const SymbolContext *prev_sc,
const ExecutionContext *exe_ctx,
@@ -296,13 +293,13 @@ public:
bool
GetAutoConfirm () const;
- const char *
+ const FormatEntity::Entry *
GetDisassemblyFormat() const;
- const char *
+ const FormatEntity::Entry *
GetFrameFormat() const;
- const char *
+ const FormatEntity::Entry *
GetThreadFormat() const;
lldb::ScriptLanguage
@@ -352,7 +349,6 @@ public:
bool
GetNotifyVoid () const;
-
const ConstString &
GetInstanceName()
diff --git a/include/lldb/Core/Disassembler.h b/include/lldb/Core/Disassembler.h
index b0b841b0a925..64d35e67bfd0 100644
--- a/include/lldb/Core/Disassembler.h
+++ b/include/lldb/Core/Disassembler.h
@@ -117,7 +117,7 @@ public:
/// the InstructionList.
/// Only needed if show_address is true.
///
- /// @param[in] disassembly_addr_format_spec
+ /// @param[in] disassembly_addr_format
/// The format specification for how addresses are printed.
/// Only needed if show_address is true.
//------------------------------------------------------------------
@@ -130,7 +130,7 @@ public:
const ExecutionContext* exe_ctx,
const SymbolContext *sym_ctx,
const SymbolContext *prev_sym_ctx,
- const char *disassembly_addr_format_spec);
+ const FormatEntity::Entry *disassembly_addr_format);
virtual bool
DoesBranch () = 0;
@@ -457,7 +457,7 @@ protected:
//------------------------------------------------------------------
// Classes that inherit from Disassembler can see and modify these
//------------------------------------------------------------------
- const ArchSpec m_arch;
+ ArchSpec m_arch;
InstructionList m_instruction_list;
lldb::addr_t m_base_addr;
std::string m_flavor;
diff --git a/include/lldb/Core/FormatEntity.h b/include/lldb/Core/FormatEntity.h
new file mode 100644
index 000000000000..32ff9ea4e3eb
--- /dev/null
+++ b/include/lldb/Core/FormatEntity.h
@@ -0,0 +1,260 @@
+//===-- FormatEntity.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_FormatEntity_h_
+#define liblldb_FormatEntity_h_
+#if defined(__cplusplus)
+
+#include <string>
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Error.h"
+
+namespace llvm
+{
+ class StringRef;
+}
+
+namespace lldb_private
+{
+ class FormatEntity
+ {
+ public:
+ struct Entry
+ {
+ enum class Type {
+ Invalid,
+ ParentNumber,
+ ParentString,
+ InsertString,
+ Root,
+ String,
+ Scope,
+ Variable,
+ VariableSynthetic,
+ ScriptVariable,
+ ScriptVariableSynthetic,
+ AddressLoad,
+ AddressFile,
+ AddressLoadOrFile,
+ ProcessID,
+ ProcessFile,
+ ScriptProcess,
+ ThreadID,
+ ThreadProtocolID,
+ ThreadIndexID,
+ ThreadName,
+ ThreadQueue,
+ ThreadStopReason,
+ ThreadReturnValue,
+ ThreadCompletedExpression,
+ ScriptThread,
+ ThreadInfo,
+ TargetArch,
+ ScriptTarget,
+ ModuleFile,
+ File,
+ FrameIndex,
+ FrameRegisterPC,
+ FrameRegisterSP,
+ FrameRegisterFP,
+ FrameRegisterFlags,
+ FrameRegisterByName,
+ ScriptFrame,
+ FunctionID,
+ FunctionDidChange,
+ FunctionInitialFunction,
+ FunctionName,
+ FunctionNameWithArgs,
+ FunctionNameNoArgs,
+ FunctionAddrOffset,
+ FunctionAddrOffsetConcrete,
+ FunctionLineOffset,
+ FunctionPCOffset,
+ LineEntryFile,
+ LineEntryLineNumber,
+ LineEntryStartAddress,
+ LineEntryEndAddress,
+ CurrentPCArrow
+ };
+
+ enum FormatType
+ {
+ None,
+ UInt32,
+ UInt64,
+ CString
+ };
+
+ struct Definition
+ {
+ const char *name;
+ const char *string; // Insert this exact string into the output
+ Entry::Type type;
+ FormatType format_type; // uint32_t, uint64_t, cstr, or anything that can be formatted by printf or lldb::Format
+ uint64_t data;
+ uint32_t num_children;
+ Definition *children; // An array of "num_children" Definition entries,
+ bool keep_separator;
+ };
+
+ Entry (Type t = Type::Invalid,
+ const char *s = NULL,
+ const char *f = NULL) :
+ string (s ? s : ""),
+ printf_format (f ? f : ""),
+ children (),
+ definition (NULL),
+ type (t),
+ fmt (lldb::eFormatDefault),
+ number (0),
+ deref (false)
+ {
+ }
+
+ Entry (llvm::StringRef s);
+ Entry (char ch);
+
+ void
+ AppendChar (char ch);
+
+ void
+ AppendText (const llvm::StringRef &s);
+
+ void
+ AppendText (const char *cstr);
+
+ void
+ AppendEntry (const Entry &&entry)
+ {
+ children.push_back(entry);
+ }
+
+ void
+ Clear ()
+ {
+ string.clear();
+ printf_format.clear();
+ children.clear();
+ definition = NULL;
+ type = Type::Invalid;
+ fmt = lldb::eFormatDefault;
+ number = 0;
+ deref = false;
+ }
+
+ static const char *
+ TypeToCString (Type t);
+
+ void
+ Dump (Stream &s, int depth = 0) const;
+
+ bool
+ operator == (const Entry &rhs) const
+ {
+ if (string != rhs.string)
+ return false;
+ if (printf_format != rhs.printf_format)
+ return false;
+ const size_t n = children.size();
+ const size_t m = rhs.children.size();
+ for (size_t i=0; i < std::min<size_t>(n, m); ++i)
+ {
+ if (!(children[i] == rhs.children[i]))
+ return false;
+ }
+ if (children != rhs.children)
+ return false;
+ if (definition != rhs.definition)
+ return false;
+ if (type != rhs.type)
+ return false;
+ if (fmt != rhs.fmt)
+ return false;
+ if (deref != rhs.deref)
+ return false;
+ return true;
+ }
+
+ std::string string;
+ std::string printf_format;
+ std::vector<Entry> children;
+ Definition *definition;
+ Type type;
+ lldb::Format fmt;
+ lldb::addr_t number;
+ bool deref;
+ };
+
+ static bool
+ Format (const Entry &entry,
+ Stream &s,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ const Address *addr,
+ ValueObject* valobj,
+ bool function_changed,
+ bool initial_function);
+
+ static bool
+ FormatStringRef (const llvm::StringRef &format,
+ Stream &s,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ const Address *addr,
+ ValueObject* valobj,
+ bool function_changed,
+ bool initial_function);
+
+ static bool
+ FormatCString (const char *format,
+ Stream &s,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ const Address *addr,
+ ValueObject* valobj,
+ bool function_changed,
+ bool initial_function);
+
+ static Error
+ Parse (const llvm::StringRef &format, Entry &entry);
+
+ static Error
+ ExtractVariableInfo (llvm::StringRef &format_str,
+ llvm::StringRef &variable_name,
+ llvm::StringRef &variable_format);
+
+ static size_t
+ AutoComplete (const char *s,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches);
+
+ //----------------------------------------------------------------------
+ // Format the current elements into the stream \a s.
+ //
+ // The root element will be stripped off and the format str passed in
+ // will be either an empty string (print a description of this object),
+ // or contain a . separated series like a domain name that identifies
+ // further sub elements to display.
+ //----------------------------------------------------------------------
+ static bool
+ FormatFileSpec (const FileSpec &file, Stream &s, llvm::StringRef elements, llvm::StringRef element_format);
+ protected:
+
+ static Error
+ ParseInternal (llvm::StringRef &format, Entry &parent_entry, uint32_t depth);
+
+ };
+
+}
+#endif // #if defined(__cplusplus)
+#endif // liblldb_FormatEntity_h_
diff --git a/include/lldb/Core/Mangled.h b/include/lldb/Core/Mangled.h
index 2f3df6afd8dc..87b23799882f 100644
--- a/include/lldb/Core/Mangled.h
+++ b/include/lldb/Core/Mangled.h
@@ -290,6 +290,25 @@ public:
void
SetValue (const ConstString &name);
+ //----------------------------------------------------------------------
+ /// Get the language only if it is definitive what the language is from
+ /// the mangling.
+ ///
+ /// For a mangled name to have a language it must have both a mangled
+ /// and a demangled name and it must be definitive from the mangling
+ /// what the language is.
+ ///
+ /// Standard C function names will return eLanguageTypeUnknown because
+ /// they aren't mangled and it isn't clear what language the name
+ /// represents (there will be no mangled name).
+ ///
+ /// @return
+ /// The language for the mangled/demangled name, eLanguageTypeUnknown
+ /// if there is no mangled or demangled counterpart.
+ //----------------------------------------------------------------------
+ lldb::LanguageType
+ GetLanguage ();
+
private:
//----------------------------------------------------------------------
/// Mangled member variables.
diff --git a/include/lldb/Core/Module.h b/include/lldb/Core/Module.h
index bfde7cbc5db9..60fbb989502e 100644
--- a/include/lldb/Core/Module.h
+++ b/include/lldb/Core/Module.h
@@ -941,17 +941,8 @@ public:
const ConstString &object_name);
bool
- GetIsDynamicLinkEditor () const
- {
- return m_is_dynamic_loader_module;
- }
-
- void
- SetIsDynamicLinkEditor (bool b)
- {
- m_is_dynamic_loader_module = b;
- }
-
+ GetIsDynamicLinkEditor ();
+
ClangASTContext &
GetClangASTContext ();
@@ -1124,8 +1115,7 @@ protected:
bool m_did_load_objfile:1,
m_did_load_symbol_vendor:1,
m_did_parse_uuid:1,
- m_did_init_ast:1,
- m_is_dynamic_loader_module:1;
+ m_did_init_ast:1;
mutable bool m_file_has_changed:1,
m_first_file_changed_log:1; /// See if the module was modified after it was initially opened.
diff --git a/include/lldb/Core/RegularExpression.h b/include/lldb/Core/RegularExpression.h
index 00d8310b4806..a58d17b4a794 100644
--- a/include/lldb/Core/RegularExpression.h
+++ b/include/lldb/Core/RegularExpression.h
@@ -121,23 +121,6 @@ public:
//------------------------------------------------------------------
RegularExpression ();
- //------------------------------------------------------------------
- /// Constructor that takes a regular expression with flags.
- ///
- /// Constructor that compiles \a re using \a flags and stores the
- /// resulting compiled regular expression into this object.
- ///
- /// @param[in] re
- /// A c string that represents the regular expression to
- /// compile.
- ///
- /// @param[in] flags
- /// Flags that are passed to the \c regcomp() function.
- //------------------------------------------------------------------
- explicit
- RegularExpression (const char* re, int flags);
-
- // This one uses flags = REG_EXTENDED.
explicit
RegularExpression (const char* re);
@@ -157,7 +140,7 @@ public:
/// Compile a regular expression.
///
/// Compile a regular expression using the supplied regular
- /// expression text and flags. The compiled regular expression lives
+ /// expression text. The compiled regular expression lives
/// in this object so that it can be readily used for regular
/// expression matches. Execute() can be called after the regular
/// expression is compiled. Any previously compiled regular
@@ -167,9 +150,6 @@ public:
/// A NULL terminated C string that represents the regular
/// expression to compile.
///
- /// @param[in] flags
- /// Flags that are passed to the \c regcomp() function.
- ///
/// @return
/// \b true if the regular expression compiles successfully,
/// \b false otherwise.
@@ -177,9 +157,6 @@ public:
bool
Compile (const char* re);
- bool
- Compile (const char* re, int flags);
-
//------------------------------------------------------------------
/// Executes a regular expression.
///
@@ -187,8 +164,7 @@ public:
/// expression that is already in this object against the match
/// string \a s. If any parens are used for regular expression
/// matches \a match_count should indicate the number of regmatch_t
- /// values that are present in \a match_ptr. The regular expression
- /// will be executed using the \a execute_flags
+ /// values that are present in \a match_ptr.
///
/// @param[in] string
/// The string to match against the compile regular expression.
@@ -198,15 +174,12 @@ public:
/// properly initialized with the desired number of maximum
/// matches, or NULL if no parenthesized matching is needed.
///
- /// @param[in] execute_flags
- /// Flags to pass to the \c regexec() function.
- ///
/// @return
/// \b true if \a string matches the compiled regular
/// expression, \b false otherwise.
//------------------------------------------------------------------
bool
- Execute (const char* string, Match *match = NULL, int execute_flags = 0) const;
+ Execute (const char* string, Match *match = NULL) const;
size_t
GetErrorAsCString (char *err_str, size_t err_str_max_len) const;
@@ -233,12 +206,6 @@ public:
const char*
GetText () const;
- int
- GetCompileFlags () const
- {
- return m_compile_flags;
- }
-
//------------------------------------------------------------------
/// Test if valid.
///
@@ -256,7 +223,6 @@ public:
{
Free();
m_re.clear();
- m_compile_flags = 0;
m_comp_err = 1;
}
@@ -276,7 +242,6 @@ private:
std::string m_re; ///< A copy of the original regular expression text
int m_comp_err; ///< Error code for the regular expression compilation
regex_t m_preg; ///< The compiled regular expression
- int m_compile_flags; ///< Stores the flags from the last compile.
};
} // namespace lldb_private
diff --git a/include/lldb/Core/ValueObject.h b/include/lldb/Core/ValueObject.h
index fa96c8989913..b50adfb69564 100644
--- a/include/lldb/Core/ValueObject.h
+++ b/include/lldb/Core/ValueObject.h
@@ -527,9 +527,14 @@ public:
virtual lldb::ModuleSP
GetModule();
- virtual ValueObject*
+ ValueObject*
GetRoot ();
+ // Given a ValueObject, loop over itself and its parent, and its parent's parent, ..
+ // until either the given callback returns false, or you end up at a null pointer
+ ValueObject*
+ FollowParentChain (std::function<bool(ValueObject*)>);
+
virtual bool
GetDeclaration (Declaration &decl);
@@ -875,6 +880,9 @@ public:
virtual lldb::LanguageType
GetPreferredDisplayLanguage ();
+ void
+ SetPreferredDisplayLanguage (lldb::LanguageType);
+
lldb::TypeSummaryImplSP
GetSummaryFormat()
{
@@ -1106,6 +1114,8 @@ protected:
llvm::SmallVector<uint8_t, 16> m_value_checksum;
+ lldb::LanguageType m_preferred_display_language;
+
bool m_value_is_valid:1,
m_value_did_change:1,
m_children_count_valid:1,
diff --git a/include/lldb/Core/ValueObjectSyntheticFilter.h b/include/lldb/Core/ValueObjectSyntheticFilter.h
index 49c5601dc0e5..aa784add7409 100644
--- a/include/lldb/Core/ValueObjectSyntheticFilter.h
+++ b/include/lldb/Core/ValueObjectSyntheticFilter.h
@@ -140,6 +140,9 @@ public:
return (UpdateValueIfNeeded(), m_provides_value == eLazyBoolYes);
}
+ virtual bool
+ SetValueFromCString (const char *value_str, Error& error);
+
protected:
virtual bool
UpdateValue ();
diff --git a/include/lldb/DataFormatters/TypeSummary.h b/include/lldb/DataFormatters/TypeSummary.h
index 2d4e03ad9b5d..8b90dd0c4895 100644
--- a/include/lldb/DataFormatters/TypeSummary.h
+++ b/include/lldb/DataFormatters/TypeSummary.h
@@ -23,6 +23,8 @@
#include "lldb/lldb-public.h"
#include "lldb/lldb-enumerations.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Interpreter/ScriptInterpreterPython.h"
#include "lldb/Symbol/Type.h"
@@ -372,31 +374,27 @@ namespace lldb_private {
// simple string-based summaries, using ${var to show data
struct StringSummaryFormat : public TypeSummaryImpl
{
- std::string m_format;
+ std::string m_format_str;
+ FormatEntity::Entry m_format;
+ Error m_error;
StringSummaryFormat(const TypeSummaryImpl::Flags& flags,
const char* f);
+ virtual
+ ~StringSummaryFormat()
+ {
+ }
+
const char*
GetSummaryString () const
{
- return m_format.c_str();
+ return m_format_str.c_str();
}
void
- SetSummaryString (const char* data)
- {
- if (data)
- m_format.assign(data);
- else
- m_format.clear();
- }
-
- virtual
- ~StringSummaryFormat()
- {
- }
-
+ SetSummaryString (const char* f);
+
virtual bool
FormatObject(ValueObject *valobj,
std::string& dest,
diff --git a/include/lldb/Expression/ASTResultSynthesizer.h b/include/lldb/Expression/ASTResultSynthesizer.h
index 79709de3546a..410a862fc12a 100644
--- a/include/lldb/Expression/ASTResultSynthesizer.h
+++ b/include/lldb/Expression/ASTResultSynthesizer.h
@@ -91,7 +91,7 @@ public:
//----------------------------------------------------------------------
/// Passthrough stub
//----------------------------------------------------------------------
- void HandleVTable(clang::CXXRecordDecl *RD, bool DefinitionRequired);
+ void HandleVTable(clang::CXXRecordDecl *RD);
//----------------------------------------------------------------------
/// Passthrough stub
diff --git a/include/lldb/Expression/ASTStructExtractor.h b/include/lldb/Expression/ASTStructExtractor.h
index 9e467797a398..25193744c9e0 100644
--- a/include/lldb/Expression/ASTStructExtractor.h
+++ b/include/lldb/Expression/ASTStructExtractor.h
@@ -99,7 +99,7 @@ public:
//----------------------------------------------------------------------
/// Passthrough stub
//----------------------------------------------------------------------
- void HandleVTable(clang::CXXRecordDecl *RD, bool DefinitionRequired);
+ void HandleVTable(clang::CXXRecordDecl *RD);
//----------------------------------------------------------------------
/// Passthrough stub
diff --git a/include/lldb/Expression/IRExecutionUnit.h b/include/lldb/Expression/IRExecutionUnit.h
index c15c65c92a3b..bd1a795a158e 100644
--- a/include/lldb/Expression/IRExecutionUnit.h
+++ b/include/lldb/Expression/IRExecutionUnit.h
@@ -207,6 +207,9 @@ private:
DisassembleFunction (Stream &stream,
lldb::ProcessSP &process_sp);
+ void
+ ReportSymbolLookupError(const ConstString &name);
+
class MemoryManager : public llvm::SectionMemoryManager
{
public:
@@ -282,10 +285,10 @@ private:
//------------------------------------------------------------------
/// Passthrough interface stub
//------------------------------------------------------------------
+ virtual uint64_t getSymbolAddress(const std::string &Name);
+
virtual void *getPointerToNamedFunction(const std::string &Name,
- bool AbortOnFailure = true) {
- return m_default_mm_ap->getPointerToNamedFunction(Name, AbortOnFailure);
- }
+ bool AbortOnFailure = true);
private:
std::unique_ptr<SectionMemoryManager> m_default_mm_ap; ///< The memory allocator to use in actually creating space. All calls are passed through to it.
IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for.
@@ -390,6 +393,7 @@ private:
std::vector<std::string> m_cpu_features;
llvm::SmallVector<JittedFunction, 1> m_jitted_functions; ///< A vector of all functions that have been JITted into machine code
const ConstString m_name;
+ std::vector<ConstString> m_failed_lookups;
std::atomic<bool> m_did_jit;
diff --git a/include/lldb/Host/File.h b/include/lldb/Host/File.h
index 2738679b5e03..8219cc06fdc2 100644
--- a/include/lldb/Host/File.h
+++ b/include/lldb/Host/File.h
@@ -42,7 +42,8 @@ public:
eOpenOptionNonBlocking = (1u << 4), // File reads
eOpenOptionCanCreate = (1u << 5), // Create file if doesn't already exist
eOpenOptionCanCreateNewOnly = (1u << 6), // Can create file only if it doesn't already exist
- eOpenoptionDontFollowSymlinks = (1u << 7)
+ eOpenoptionDontFollowSymlinks = (1u << 7),
+ eOpenOptionCloseOnExec = (1u << 8) // Close the file when executing a new process
};
static mode_t
diff --git a/include/lldb/Host/Host.h b/include/lldb/Host/Host.h
index ce12689fc047..9a68c698c826 100644
--- a/include/lldb/Host/Host.h
+++ b/include/lldb/Host/Host.h
@@ -246,9 +246,6 @@ public:
static const lldb_private::UnixSignalsSP&
GetUnixSignals ();
- static lldb::pid_t
- LaunchApplication (const FileSpec &app_file_spec);
-
static Error
LaunchProcess (ProcessLaunchInfo &launch_info);
diff --git a/include/lldb/Host/PipeBase.h b/include/lldb/Host/PipeBase.h
index 8cad2507d32c..5ef2bb530281 100644
--- a/include/lldb/Host/PipeBase.h
+++ b/include/lldb/Host/PipeBase.h
@@ -14,6 +14,7 @@
#include <string>
#include "lldb/Core/Error.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
namespace lldb_private
@@ -25,6 +26,7 @@ class PipeBase
virtual Error CreateNew(bool child_process_inherit) = 0;
virtual Error CreateNew(llvm::StringRef name, bool child_process_inherit) = 0;
+ virtual Error CreateWithUniqueName(llvm::StringRef prefix, bool child_process_inherit, llvm::SmallVectorImpl<char>& name) = 0;
virtual Error OpenAsReader(llvm::StringRef name, bool child_process_inherit) = 0;
diff --git a/include/lldb/Host/Socket.h b/include/lldb/Host/Socket.h
index 77069ae35f79..ee85f85fcaf2 100644
--- a/include/lldb/Host/Socket.h
+++ b/include/lldb/Host/Socket.h
@@ -70,22 +70,35 @@ public:
int GetOption (int level, int option_name, int &option_value);
int SetOption (int level, int option_name, int option_value);
- static uint16_t GetPortNumber(const NativeSocket& socket);
- uint16_t GetPortNumber () const;
+ // returns port number or 0 if error
+ static uint16_t GetLocalPortNumber (const NativeSocket& socket);
+
+ // returns port number or 0 if error
+ uint16_t GetLocalPortNumber () const;
+
+ // returns ip address string or empty string if error
+ std::string GetLocalIPAddress () const;
+
+ // must be connected
+ // returns port number or 0 if error
+ uint16_t GetRemotePortNumber () const;
+
+ // must be connected
+ // returns ip address string or empty string if error
+ std::string GetRemoteIPAddress () const;
NativeSocket GetNativeSocket () const { return m_socket; }
- SocketProtocol GetSocketProtocol() const { return m_protocol; }
+ SocketProtocol GetSocketProtocol () const { return m_protocol; }
virtual Error Read (void *buf, size_t &num_bytes);
virtual Error Write (const void *buf, size_t &num_bytes);
- virtual Error PreDisconnect();
- virtual Error Close();
+ virtual Error PreDisconnect ();
+ virtual Error Close ();
- virtual bool IsValid() const { return m_socket != kInvalidSocketValue; }
- virtual WaitableHandle GetWaitableHandle();
+ virtual bool IsValid () const { return m_socket != kInvalidSocketValue; }
+ virtual WaitableHandle GetWaitableHandle ();
-protected:
static bool
DecodeHostAndPort (llvm::StringRef host_and_port,
std::string &host_str,
@@ -93,7 +106,7 @@ protected:
int32_t& port,
Error *error_ptr);
-
+protected:
SocketProtocol m_protocol;
NativeSocket m_socket;
SocketAddress m_udp_send_sockaddr; // Send address used for UDP connections.
diff --git a/include/lldb/Host/SocketAddress.h b/include/lldb/Host/SocketAddress.h
index 3598a42a82d0..9666f56489f6 100644
--- a/include/lldb/Host/SocketAddress.h
+++ b/include/lldb/Host/SocketAddress.h
@@ -31,6 +31,7 @@ typedef ADDRESS_FAMILY sa_family_t;
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include <string>
namespace lldb_private {
@@ -100,6 +101,12 @@ public:
SetFamily (sa_family_t family);
//------------------------------------------------------------------
+ // Get the address
+ //------------------------------------------------------------------
+ std::string
+ GetIPAddress () const;
+
+ //------------------------------------------------------------------
// Get the port if the socket address for the family has a port
//------------------------------------------------------------------
uint16_t
diff --git a/include/lldb/Host/StringConvert.h b/include/lldb/Host/StringConvert.h
new file mode 100644
index 000000000000..3cc260cf2be1
--- /dev/null
+++ b/include/lldb/Host/StringConvert.h
@@ -0,0 +1,45 @@
+//===-- StringConvert.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StringConvert_h_
+#define liblldb_StringConvert_h_
+
+// C Includes
+#include <stdint.h>
+
+// C++ Includes
+
+// Other libraries and framework includes
+// Project includes
+
+namespace lldb_private {
+
+namespace StringConvert {
+
+//----------------------------------------------------------------------
+/// @namespace StringConvert StringConvert.h "lldb/Host/StringConvert.h"
+/// @brief Utility classes for converting strings into Integers
+//----------------------------------------------------------------------
+
+int32_t
+ToSInt32 (const char *s, int32_t fail_value = 0, int base = 0, bool *success_ptr = nullptr);
+
+uint32_t
+ToUInt32 (const char *s, uint32_t fail_value = 0, int base = 0, bool *success_ptr = nullptr);
+
+int64_t
+ToSInt64 (const char *s, int64_t fail_value = 0, int base = 0, bool *success_ptr = nullptr);
+
+uint64_t
+ToUInt64 (const char *s, uint64_t fail_value = 0, int base = 0, bool *success_ptr = nullptr);
+
+} // namespace StringConvert
+} // namespace lldb_private
+
+#endif
diff --git a/source/Host/common/NativeBreakpoint.h b/include/lldb/Host/common/NativeBreakpoint.h
index 367003b94e35..367003b94e35 100644
--- a/source/Host/common/NativeBreakpoint.h
+++ b/include/lldb/Host/common/NativeBreakpoint.h
diff --git a/source/Host/common/NativeBreakpointList.h b/include/lldb/Host/common/NativeBreakpointList.h
index 51617330d075..51617330d075 100644
--- a/source/Host/common/NativeBreakpointList.h
+++ b/include/lldb/Host/common/NativeBreakpointList.h
diff --git a/source/Host/common/NativeProcessProtocol.h b/include/lldb/Host/common/NativeProcessProtocol.h
index 19d8f353b26f..83c14a5ab37a 100644
--- a/source/Host/common/NativeProcessProtocol.h
+++ b/include/lldb/Host/common/NativeProcessProtocol.h
@@ -18,6 +18,7 @@
#include "lldb/Host/Mutex.h"
#include "NativeBreakpointList.h"
+#include "NativeWatchpointList.h"
namespace lldb_private
{
@@ -130,6 +131,9 @@ namespace lldb_private
//----------------------------------------------------------------------
// Watchpoint functions
//----------------------------------------------------------------------
+ virtual const NativeWatchpointList::WatchpointMap&
+ GetWatchpointMap () const;
+
virtual uint32_t
GetMaxWatchpoints () const;
@@ -295,6 +299,7 @@ namespace lldb_private
Mutex m_delegates_mutex;
std::vector<NativeDelegate*> m_delegates;
NativeBreakpointList m_breakpoint_list;
+ NativeWatchpointList m_watchpoint_list;
int m_terminal_fd;
uint32_t m_stop_id;
diff --git a/include/lldb/Target/NativeRegisterContext.h b/include/lldb/Host/common/NativeRegisterContext.h
index fa4ab013f234..e9c03e3c20a4 100644
--- a/include/lldb/Target/NativeRegisterContext.h
+++ b/include/lldb/Host/common/NativeRegisterContext.h
@@ -15,6 +15,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
+#include "lldb/Host/common/NativeWatchpointList.h"
namespace lldb_private {
@@ -44,6 +45,9 @@ public:
virtual uint32_t
GetRegisterCount () const = 0;
+ virtual uint32_t
+ GetUserRegisterCount () const = 0;
+
virtual const RegisterInfo *
GetRegisterInfoAtIndex (uint32_t reg) const = 0;
@@ -92,6 +96,9 @@ public:
virtual bool
ClearHardwareWatchpoint (uint32_t hw_index);
+ virtual Error
+ ClearAllHardwareWatchpoints ();
+
virtual bool
HardwareSingleStep (bool enable);
diff --git a/include/lldb/Target/NativeRegisterContextRegisterInfo.h b/include/lldb/Host/common/NativeRegisterContextRegisterInfo.h
index 5631005ca56e..b2a29de4e5a4 100644
--- a/include/lldb/Target/NativeRegisterContextRegisterInfo.h
+++ b/include/lldb/Host/common/NativeRegisterContextRegisterInfo.h
@@ -31,6 +31,9 @@ namespace lldb_private
uint32_t
GetRegisterCount () const override;
+ uint32_t
+ GetUserRegisterCount () const override;
+
const RegisterInfo *
GetRegisterInfoAtIndex (uint32_t reg_index) const override;
diff --git a/source/Host/common/NativeThreadProtocol.h b/include/lldb/Host/common/NativeThreadProtocol.h
index 15ecffe8b82d..954ffb36a94f 100644
--- a/source/Host/common/NativeThreadProtocol.h
+++ b/include/lldb/Host/common/NativeThreadProtocol.h
@@ -53,10 +53,7 @@ namespace lldb_private
RestoreAllRegisters (lldb::DataBufferSP &data_sp);
virtual bool
- GetStopReason (ThreadStopInfo &stop_info) = 0;
-
- virtual uint32_t
- TranslateStopInfoToGdbSignal (const ThreadStopInfo &stop_info) const;
+ GetStopReason (ThreadStopInfo &stop_info, std::string& description) = 0;
lldb::tid_t
GetID() const
diff --git a/include/lldb/Host/common/NativeWatchpointList.h b/include/lldb/Host/common/NativeWatchpointList.h
new file mode 100644
index 000000000000..7b310e5a0db0
--- /dev/null
+++ b/include/lldb/Host/common/NativeWatchpointList.h
@@ -0,0 +1,47 @@
+//===-- NativeWatchpointList.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_NativeWatchpointList_h_
+#define liblldb_NativeWatchpointList_h_
+
+#include "lldb/lldb-private-forward.h"
+#include "lldb/Core/Error.h"
+
+#include <map>
+
+namespace lldb_private
+{
+ struct NativeWatchpoint
+ {
+ lldb::addr_t m_addr;
+ size_t m_size;
+ uint32_t m_watch_flags;
+ bool m_hardware;
+ };
+
+ class NativeWatchpointList
+ {
+ public:
+ Error
+ Add (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware);
+
+ Error
+ Remove (lldb::addr_t addr);
+
+ using WatchpointMap = std::map<lldb::addr_t, NativeWatchpoint>;
+
+ const WatchpointMap&
+ GetWatchpointMap () const;
+
+ private:
+ WatchpointMap m_watchpoints;
+ };
+}
+
+#endif // ifndef liblldb_NativeWatchpointList_h_
diff --git a/source/Host/common/SoftwareBreakpoint.h b/include/lldb/Host/common/SoftwareBreakpoint.h
index 1fed19eca612..1fed19eca612 100644
--- a/source/Host/common/SoftwareBreakpoint.h
+++ b/include/lldb/Host/common/SoftwareBreakpoint.h
diff --git a/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h b/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h
index 4d326d71fa75..660b9d169bfc 100644
--- a/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h
+++ b/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h
@@ -50,6 +50,8 @@ class ConnectionFileDescriptor : public Connection
virtual size_t Write(const void *src, size_t src_len, lldb::ConnectionStatus &status, Error *error_ptr);
+ virtual std::string GetURI();
+
lldb::ConnectionStatus BytesAvailable(uint32_t timeout_usec, Error *error_ptr);
bool InterruptRead();
@@ -75,7 +77,7 @@ class ConnectionFileDescriptor : public Connection
void CloseCommandPipe();
- lldb::ConnectionStatus SocketListen(const char *host_and_port, Error *error_ptr);
+ lldb::ConnectionStatus SocketListenAndAccept(const char *host_and_port, Error *error_ptr);
lldb::ConnectionStatus ConnectTCP(const char *host_and_port, Error *error_ptr);
@@ -99,6 +101,8 @@ class ConnectionFileDescriptor : public Connection
bool m_waiting_for_accept;
bool m_child_processes_inherit;
+ std::string m_uri;
+
private:
DISALLOW_COPY_AND_ASSIGN(ConnectionFileDescriptor);
};
diff --git a/include/lldb/Host/posix/PipePosix.h b/include/lldb/Host/posix/PipePosix.h
index 0ab3ff7f6775..fbdac66149d6 100644
--- a/include/lldb/Host/posix/PipePosix.h
+++ b/include/lldb/Host/posix/PipePosix.h
@@ -36,6 +36,8 @@ public:
Error
CreateNew(llvm::StringRef name, bool child_process_inherit) override;
Error
+ CreateWithUniqueName(llvm::StringRef prefix, bool child_process_inherit, llvm::SmallVectorImpl<char>& name) override;
+ Error
OpenAsReader(llvm::StringRef name, bool child_process_inherit) override;
Error
OpenAsWriterWithTimeout(llvm::StringRef name, bool child_process_inherit, const std::chrono::microseconds &timeout) override;
diff --git a/include/lldb/Interpreter/Args.h b/include/lldb/Interpreter/Args.h
index 1071bd6fd047..fe29df468de7 100644
--- a/include/lldb/Interpreter/Args.h
+++ b/include/lldb/Interpreter/Args.h
@@ -347,18 +347,6 @@ public:
bool trailing = true,
bool return_null_if_empty = true);
- static int32_t
- StringToSInt32 (const char *s, int32_t fail_value = 0, int base = 0, bool *success_ptr = NULL);
-
- static uint32_t
- StringToUInt32 (const char *s, uint32_t fail_value = 0, int base = 0, bool *success_ptr = NULL);
-
- static int64_t
- StringToSInt64 (const char *s, int64_t fail_value = 0, int base = 0, bool *success_ptr = NULL);
-
- static uint64_t
- StringToUInt64 (const char *s, uint64_t fail_value = 0, int base = 0, bool *success_ptr = NULL);
-
static bool
UInt64ValueIsValidForByteSize (uint64_t uval64, size_t total_byte_size)
{
diff --git a/include/lldb/Interpreter/CommandInterpreter.h b/include/lldb/Interpreter/CommandInterpreter.h
index baaa271a4285..20b6ff95be8b 100644
--- a/include/lldb/Interpreter/CommandInterpreter.h
+++ b/include/lldb/Interpreter/CommandInterpreter.h
@@ -224,6 +224,7 @@ public:
eCommandTypesBuiltin = 0x0001, // native commands such as "frame"
eCommandTypesUserDef = 0x0002, // scripted commands
eCommandTypesAliases = 0x0004, // aliases such as "po"
+ eCommandTypesHidden = 0x0008, // commands prefixed with an underscore
eCommandTypesAllThem = 0xFFFF // all commands
};
@@ -431,6 +432,11 @@ public:
StreamString &help_string);
void
+ OutputFormattedHelpText (Stream &strm,
+ const char *prefix,
+ const char *help_text);
+
+ void
OutputFormattedHelpText (Stream &stream,
const char *command_word,
const char *separator,
@@ -607,6 +613,9 @@ public:
bool asynchronously,
void *baton);
+ const char *
+ GetCommandPrefix ();
+
//------------------------------------------------------------------
// Properties
//------------------------------------------------------------------
diff --git a/include/lldb/Interpreter/OptionGroupPlatform.h b/include/lldb/Interpreter/OptionGroupPlatform.h
index 970ad328ccb7..f7de50c86a56 100644
--- a/include/lldb/Interpreter/OptionGroupPlatform.h
+++ b/include/lldb/Interpreter/OptionGroupPlatform.h
@@ -102,8 +102,10 @@ public:
SetSDKBuild (const ConstString &sdk_build)
{
m_sdk_build = sdk_build;
- }
-
+ }
+
+ bool
+ PlatformMatches(const lldb::PlatformSP &platform_sp) const;
protected:
std::string m_platform_name;
diff --git a/include/lldb/Interpreter/OptionValue.h b/include/lldb/Interpreter/OptionValue.h
index 0e8f23453a8a..787430a96ef5 100644
--- a/include/lldb/Interpreter/OptionValue.h
+++ b/include/lldb/Interpreter/OptionValue.h
@@ -17,6 +17,7 @@
#include "lldb/lldb-defines.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
+#include "lldb/Core/FormatEntity.h"
namespace lldb_private {
@@ -45,7 +46,8 @@ namespace lldb_private {
eTypeSInt64,
eTypeString,
eTypeUInt64,
- eTypeUUID
+ eTypeUUID,
+ eTypeFormatEntity
} Type;
enum {
@@ -309,7 +311,13 @@ namespace lldb_private {
const OptionValueUUID *
GetAsUUID () const;
-
+
+ OptionValueFormatEntity *
+ GetAsFormatEntity ();
+
+ const OptionValueFormatEntity *
+ GetAsFormatEntity () const;
+
bool
GetBooleanValue (bool fail_value = false) const;
@@ -341,6 +349,9 @@ namespace lldb_private {
bool
SetFormatValue (lldb::Format new_value);
+ const FormatEntity::Entry *
+ GetFormatEntity () const;
+
const RegularExpression *
GetRegexValue () const;
diff --git a/include/lldb/Interpreter/OptionValueFormatEntity.h b/include/lldb/Interpreter/OptionValueFormatEntity.h
new file mode 100644
index 000000000000..cc988998bda0
--- /dev/null
+++ b/include/lldb/Interpreter/OptionValueFormatEntity.h
@@ -0,0 +1,107 @@
+//===-- OptionValueFormatEntity.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_OptionValueFormatEntity_h_
+#define liblldb_OptionValueFormatEntity_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/FormatEntity.h"
+#include "lldb/Interpreter/OptionValue.h"
+
+namespace lldb_private {
+
+class OptionValueFormatEntity : public OptionValue
+{
+public:
+ OptionValueFormatEntity (const char *default_format);
+
+ virtual
+ ~OptionValueFormatEntity()
+ {
+ }
+
+ //---------------------------------------------------------------------
+ // Virtual subclass pure virtual overrides
+ //---------------------------------------------------------------------
+
+ OptionValue::Type
+ GetType () const override
+ {
+ return eTypeFormatEntity;
+ }
+
+ void
+ DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) override;
+
+ Error
+ SetValueFromCString (const char *value,
+ VarSetOperationType op = eVarSetOperationAssign) override;
+
+ bool
+ Clear () override;
+
+ lldb::OptionValueSP
+ DeepCopy () const override;
+
+ size_t
+ AutoComplete (CommandInterpreter &interpreter,
+ const char *s,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override;
+
+ //---------------------------------------------------------------------
+ // Subclass specific functions
+ //---------------------------------------------------------------------
+
+ FormatEntity::Entry &
+ GetCurrentValue()
+ {
+ return m_current_entry;
+ }
+
+ const FormatEntity::Entry &
+ GetCurrentValue() const
+ {
+ return m_current_entry;
+ }
+
+ void
+ SetCurrentValue (const FormatEntity::Entry &value)
+ {
+ m_current_entry = value;
+ }
+
+ FormatEntity::Entry &
+ GetDefaultValue()
+ {
+ return m_default_entry;
+ }
+
+ const FormatEntity::Entry &
+ GetDefaultValue() const
+ {
+ return m_default_entry;
+ }
+
+
+protected:
+ std::string m_current_format;
+ std::string m_default_format;
+ FormatEntity::Entry m_current_entry;
+ FormatEntity::Entry m_default_entry;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OptionValueFormatEntity_h_
diff --git a/include/lldb/Interpreter/OptionValueProperties.h b/include/lldb/Interpreter/OptionValueProperties.h
index a67ea5d66e54..6f7f4995ed15 100644
--- a/include/lldb/Interpreter/OptionValueProperties.h
+++ b/include/lldb/Interpreter/OptionValueProperties.h
@@ -15,6 +15,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/ConstString.h"
+#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Interpreter/OptionValue.h"
#include "lldb/Interpreter/Property.h"
@@ -191,6 +192,9 @@ public:
bool
SetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value);
+ const FormatEntity::Entry *
+ GetPropertyAtIndexAsFormatEntity (const ExecutionContext *exe_ctx, uint32_t idx);
+
const RegularExpression *
GetPropertyAtIndexAsOptionValueRegex (const ExecutionContext *exe_ctx, uint32_t idx) const;
diff --git a/include/lldb/Interpreter/OptionValueRegex.h b/include/lldb/Interpreter/OptionValueRegex.h
index bb8c4588e22a..295bb98b69e6 100644
--- a/include/lldb/Interpreter/OptionValueRegex.h
+++ b/include/lldb/Interpreter/OptionValueRegex.h
@@ -24,9 +24,9 @@ namespace lldb_private {
class OptionValueRegex : public OptionValue
{
public:
- OptionValueRegex (const char *value = NULL, uint32_t regex_flags = 0) :
+ OptionValueRegex (const char *value = NULL) :
OptionValue(),
- m_regex (value, regex_flags)
+ m_regex (value)
{
}
@@ -75,10 +75,10 @@ public:
}
void
- SetCurrentValue (const char *value, uint32_t regex_flags)
+ SetCurrentValue (const char *value)
{
if (value && value[0])
- m_regex.Compile (value, regex_flags);
+ m_regex.Compile (value);
else
m_regex.Clear();
}
diff --git a/include/lldb/Interpreter/OptionValues.h b/include/lldb/Interpreter/OptionValues.h
index c66fc4dab2f6..2ccab994674b 100644
--- a/include/lldb/Interpreter/OptionValues.h
+++ b/include/lldb/Interpreter/OptionValues.h
@@ -21,6 +21,7 @@
#include "lldb/Interpreter/OptionValueFileSpec.h"
#include "lldb/Interpreter/OptionValueFileSpecList.h"
#include "lldb/Interpreter/OptionValueFormat.h"
+#include "lldb/Interpreter/OptionValueFormatEntity.h"
#include "lldb/Interpreter/OptionValuePathMappings.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/OptionValueRegex.h"
diff --git a/include/lldb/Interpreter/ScriptInterpreter.h b/include/lldb/Interpreter/ScriptInterpreter.h
index 35ba9491ded0..1b4b88161927 100644
--- a/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/include/lldb/Interpreter/ScriptInterpreter.h
@@ -240,7 +240,13 @@ public:
bool m_set_lldb_globals;
bool m_maskout_errors;
};
-
+
+ virtual bool
+ Interrupt()
+ {
+ return false;
+ }
+
virtual bool
ExecuteOneLine (const char *command,
CommandReturnObject *result,
@@ -290,13 +296,13 @@ public:
}
virtual bool
- GenerateTypeScriptFunction (const char* oneliner, std::string& output, void* name_token = NULL)
+ GenerateTypeScriptFunction (const char* oneliner, std::string& output, const void* name_token = NULL)
{
return false;
}
virtual bool
- GenerateTypeScriptFunction (StringList &input, std::string& output, void* name_token = NULL)
+ GenerateTypeScriptFunction (StringList &input, std::string& output, const void* name_token = NULL)
{
return false;
}
@@ -308,13 +314,13 @@ public:
}
virtual bool
- GenerateTypeSynthClass (StringList &input, std::string& output, void* name_token = NULL)
+ GenerateTypeSynthClass (StringList &input, std::string& output, const void* name_token = NULL)
{
return false;
}
virtual bool
- GenerateTypeSynthClass (const char* oneliner, std::string& output, void* name_token = NULL)
+ GenerateTypeSynthClass (const char* oneliner, std::string& output, const void* name_token = NULL)
{
return false;
}
diff --git a/include/lldb/Interpreter/ScriptInterpreterPython.h b/include/lldb/Interpreter/ScriptInterpreterPython.h
index edcc4c44facb..94ed16e02ca2 100644
--- a/include/lldb/Interpreter/ScriptInterpreterPython.h
+++ b/include/lldb/Interpreter/ScriptInterpreterPython.h
@@ -41,125 +41,128 @@ public:
~ScriptInterpreterPython ();
bool
+ Interrupt() override;
+
+ bool
ExecuteOneLine (const char *command,
CommandReturnObject *result,
- const ExecuteScriptOptions &options = ExecuteScriptOptions());
+ const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
void
- ExecuteInterpreterLoop ();
+ ExecuteInterpreterLoop () override;
bool
ExecuteOneLineWithReturn (const char *in_string,
ScriptInterpreter::ScriptReturnType return_type,
void *ret_value,
- const ExecuteScriptOptions &options = ExecuteScriptOptions());
+ const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
lldb_private::Error
ExecuteMultipleLines (const char *in_string,
- const ExecuteScriptOptions &options = ExecuteScriptOptions());
+ const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
Error
- ExportFunctionDefinitionToInterpreter (StringList &function_def);
+ ExportFunctionDefinitionToInterpreter (StringList &function_def) override;
bool
- GenerateTypeScriptFunction (StringList &input, std::string& output, void* name_token = NULL);
+ GenerateTypeScriptFunction (StringList &input, std::string& output, const void* name_token = NULL) override;
bool
- GenerateTypeSynthClass (StringList &input, std::string& output, void* name_token = NULL);
+ GenerateTypeSynthClass (StringList &input, std::string& output, const void* name_token = NULL) override;
bool
- GenerateTypeSynthClass (const char* oneliner, std::string& output, void* name_token = NULL);
+ GenerateTypeSynthClass (const char* oneliner, std::string& output, const void* name_token = NULL) override;
// use this if the function code is just a one-liner script
bool
- GenerateTypeScriptFunction (const char* oneliner, std::string& output, void* name_token = NULL);
+ GenerateTypeScriptFunction (const char* oneliner, std::string& output, const void* name_token = NULL) override;
- virtual bool
- GenerateScriptAliasFunction (StringList &input, std::string& output);
+ bool
+ GenerateScriptAliasFunction (StringList &input, std::string& output) override;
lldb::ScriptInterpreterObjectSP
CreateSyntheticScriptedProvider (const char *class_name,
- lldb::ValueObjectSP valobj);
+ lldb::ValueObjectSP valobj) override;
lldb::ScriptInterpreterObjectSP
- virtual CreateScriptedThreadPlan (const char *class_name,
- lldb::ThreadPlanSP thread_plan);
+ CreateScriptedThreadPlan (const char *class_name,
+ lldb::ThreadPlanSP thread_plan) override;
- virtual bool
+ bool
ScriptedThreadPlanExplainsStop (lldb::ScriptInterpreterObjectSP implementor_sp,
Event *event,
- bool &script_error);
- virtual bool
+ bool &script_error) override;
+ bool
ScriptedThreadPlanShouldStop (lldb::ScriptInterpreterObjectSP implementor_sp,
Event *event,
- bool &script_error);
- virtual lldb::StateType
+ bool &script_error) override;
+ lldb::StateType
ScriptedThreadPlanGetRunState (lldb::ScriptInterpreterObjectSP implementor_sp,
- bool &script_error);
+ bool &script_error) override;
- virtual lldb::ScriptInterpreterObjectSP
+ lldb::ScriptInterpreterObjectSP
OSPlugin_CreatePluginObject (const char *class_name,
- lldb::ProcessSP process_sp);
+ lldb::ProcessSP process_sp) override;
- virtual lldb::ScriptInterpreterObjectSP
- OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp);
+ lldb::ScriptInterpreterObjectSP
+ OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp) override;
- virtual lldb::ScriptInterpreterObjectSP
- OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp);
+ lldb::ScriptInterpreterObjectSP
+ OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp) override;
- virtual lldb::ScriptInterpreterObjectSP
+ lldb::ScriptInterpreterObjectSP
OSPlugin_RegisterContextData (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
- lldb::tid_t thread_id);
+ lldb::tid_t thread_id) override;
- virtual lldb::ScriptInterpreterObjectSP
+ lldb::ScriptInterpreterObjectSP
OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
lldb::tid_t tid,
- lldb::addr_t context);
+ lldb::addr_t context) override;
- virtual lldb::ScriptInterpreterObjectSP
+ lldb::ScriptInterpreterObjectSP
LoadPluginModule (const FileSpec& file_spec,
- lldb_private::Error& error);
+ lldb_private::Error& error) override;
- virtual lldb::ScriptInterpreterObjectSP
+ lldb::ScriptInterpreterObjectSP
GetDynamicSettings (lldb::ScriptInterpreterObjectSP plugin_module_sp,
Target* target,
const char* setting_name,
- lldb_private::Error& error);
+ lldb_private::Error& error) override;
- virtual size_t
- CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor);
+ size_t
+ CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor) override;
- virtual lldb::ValueObjectSP
- GetChildAtIndex (const lldb::ScriptInterpreterObjectSP& implementor, uint32_t idx);
+ lldb::ValueObjectSP
+ GetChildAtIndex (const lldb::ScriptInterpreterObjectSP& implementor, uint32_t idx) override;
- virtual int
- GetIndexOfChildWithName (const lldb::ScriptInterpreterObjectSP& implementor, const char* child_name);
+ int
+ GetIndexOfChildWithName (const lldb::ScriptInterpreterObjectSP& implementor, const char* child_name) override;
- virtual bool
- UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor);
+ bool
+ UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor) override;
- virtual bool
- MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor);
+ bool
+ MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor) override;
- virtual lldb::ValueObjectSP
- GetSyntheticValue (const lldb::ScriptInterpreterObjectSP& implementor);
+ lldb::ValueObjectSP
+ GetSyntheticValue (const lldb::ScriptInterpreterObjectSP& implementor) override;
- virtual bool
+ bool
RunScriptBasedCommand(const char* impl_function,
const char* args,
ScriptedCommandSynchronicity synchronicity,
lldb_private::CommandReturnObject& cmd_retobj,
Error& error,
- const lldb_private::ExecutionContext& exe_ctx);
+ const lldb_private::ExecutionContext& exe_ctx) override;
Error
- GenerateFunction(const char *signature, const StringList &input);
+ GenerateFunction(const char *signature, const StringList &input) override;
Error
- GenerateBreakpointCommandCallbackData (StringList &input, std::string& output);
+ GenerateBreakpointCommandCallbackData (StringList &input, std::string& output) override;
bool
- GenerateWatchpointCommandCallbackData (StringList &input, std::string& output);
+ GenerateWatchpointCommandCallbackData (StringList &input, std::string& output) override;
// static size_t
// GenerateBreakpointOptionsCommandCallback (void *baton,
@@ -186,21 +189,21 @@ public:
StoppointCallbackContext *context,
lldb::user_id_t watch_id);
- virtual bool
+ bool
GetScriptedSummary (const char *function_name,
lldb::ValueObjectSP valobj,
lldb::ScriptInterpreterObjectSP& callee_wrapper_sp,
const TypeSummaryOptions& options,
- std::string& retval);
+ std::string& retval) override;
- virtual void
- Clear ();
+ void
+ Clear () override;
- virtual bool
- GetDocumentationForItem (const char* item, std::string& dest);
+ bool
+ GetDocumentationForItem (const char* item, std::string& dest) override;
- virtual bool
- CheckObjectExists (const char* name)
+ bool
+ CheckObjectExists (const char* name) override
{
if (!name || !name[0])
return false;
@@ -208,76 +211,76 @@ public:
return GetDocumentationForItem (name,temp);
}
- virtual bool
+ bool
RunScriptFormatKeyword (const char* impl_function,
Process* process,
std::string& output,
- Error& error);
+ Error& error) override;
- virtual bool
+ bool
RunScriptFormatKeyword (const char* impl_function,
Thread* thread,
std::string& output,
- Error& error);
+ Error& error) override;
- virtual bool
+ bool
RunScriptFormatKeyword (const char* impl_function,
Target* target,
std::string& output,
- Error& error);
+ Error& error) override;
- virtual bool
+ bool
RunScriptFormatKeyword (const char* impl_function,
StackFrame* frame,
std::string& output,
- Error& error);
+ Error& error) override;
- virtual bool
+ bool
RunScriptFormatKeyword (const char* impl_function,
ValueObject* value,
std::string& output,
- Error& error);
+ Error& error) override;
- virtual bool
+ bool
LoadScriptingModule (const char* filename,
bool can_reload,
bool init_session,
lldb_private::Error& error,
- lldb::ScriptInterpreterObjectSP* module_sp = nullptr);
+ lldb::ScriptInterpreterObjectSP* module_sp = nullptr) override;
- virtual lldb::ScriptInterpreterObjectSP
- MakeScriptObject (void* object);
+ lldb::ScriptInterpreterObjectSP
+ MakeScriptObject (void* object) override;
- virtual std::unique_ptr<ScriptInterpreterLocker>
- AcquireInterpreterLock ();
+ std::unique_ptr<ScriptInterpreterLocker>
+ AcquireInterpreterLock () override;
void
CollectDataForBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec,
- CommandReturnObject &result);
+ CommandReturnObject &result) override;
void
CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options,
- CommandReturnObject &result);
+ CommandReturnObject &result) override;
/// Set the callback body text into the callback for the breakpoint.
Error
SetBreakpointCommandCallback (BreakpointOptions *bp_options,
- const char *callback_body);
+ const char *callback_body) override;
void
SetBreakpointCommandCallbackFunction (BreakpointOptions *bp_options,
- const char *function_name);
+ const char *function_name) override;
/// Set a one-liner as the callback for the watchpoint.
void
SetWatchpointCommandCallback (WatchpointOptions *wp_options,
- const char *oneliner);
+ const char *oneliner) override;
StringList
ReadCommandInputFromUser (FILE *in_file);
virtual void
- ResetOutputFileHandle (FILE *new_fh);
+ ResetOutputFileHandle (FILE *new_fh) override;
static void
InitializePrivate ();
@@ -331,11 +334,11 @@ public:
//----------------------------------------------------------------------
// IOHandlerDelegate
//----------------------------------------------------------------------
- virtual void
- IOHandlerActivated (IOHandler &io_handler);
+ void
+ IOHandlerActivated (IOHandler &io_handler) override;
- virtual void
- IOHandlerInputComplete (IOHandler &io_handler, std::string &data);
+ void
+ IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override;
protected:
@@ -448,6 +451,26 @@ public:
};
protected:
+ uint32_t
+ IsExecutingPython () const
+ {
+ return m_lock_count > 0;
+ }
+
+ uint32_t
+ IncrementLockCount()
+ {
+ return ++m_lock_count;
+ }
+
+ uint32_t
+ DecrementLockCount()
+ {
+ if (m_lock_count > 0)
+ --m_lock_count;
+ return m_lock_count;
+ }
+
enum ActiveIOHandler {
eIOHandlerNone,
eIOHandlerBreakpoint,
@@ -480,6 +503,7 @@ protected:
bool m_session_is_active;
bool m_pty_slave_is_open;
bool m_valid_session;
+ uint32_t m_lock_count;
PyThreadState *m_command_thread_state;
};
} // namespace lldb_private
diff --git a/include/lldb/Symbol/ClangASTType.h b/include/lldb/Symbol/ClangASTType.h
index ef23a8be645b..94c768780a00 100644
--- a/include/lldb/Symbol/ClangASTType.h
+++ b/include/lldb/Symbol/ClangASTType.h
@@ -97,6 +97,10 @@ public:
bool *is_incomplete) const;
bool
+ IsVectorType (ClangASTType *element_type,
+ uint64_t *size) const;
+
+ bool
IsArrayOfScalarType () const;
bool
@@ -347,10 +351,10 @@ public:
//----------------------------------------------------------------------
uint64_t
- GetByteSize () const;
+ GetByteSize (ExecutionContext *exe_ctx) const;
uint64_t
- GetBitSize () const;
+ GetBitSize (ExecutionContext *exe_ctx) const;
lldb::Encoding
GetEncoding (uint64_t &count) const;
diff --git a/include/lldb/Symbol/ObjectFile.h b/include/lldb/Symbol/ObjectFile.h
index bdc6ae8c9e81..8bcf92de42e5 100644
--- a/include/lldb/Symbol/ObjectFile.h
+++ b/include/lldb/Symbol/ObjectFile.h
@@ -767,6 +767,23 @@ public:
return 0;
}
+
+ //------------------------------------------------------------------
+ /// Return true if this file is a dynamic link editor (dyld)
+ ///
+ /// Often times dyld has symbols that mirror symbols in libc and
+ /// other shared libraries (like "malloc" and "free") and the user
+ /// does _not_ want to stop in these shared libraries by default.
+ /// We can ask the ObjectFile if it is such a file and should be
+ /// avoided for things like settings breakpoints and doing function
+ /// lookups for expressions.
+ //------------------------------------------------------------------
+ virtual bool
+ GetIsDynamicLinkEditor()
+ {
+ return false;
+ }
+
//------------------------------------------------------------------
// Member Functions
//------------------------------------------------------------------
diff --git a/include/lldb/Symbol/SymbolContext.h b/include/lldb/Symbol/SymbolContext.h
index d40d1453cb17..64490627b84d 100644
--- a/include/lldb/Symbol/SymbolContext.h
+++ b/include/lldb/Symbol/SymbolContext.h
@@ -347,6 +347,7 @@ public:
Block * block; ///< The Block for a given query
LineEntry line_entry; ///< The LineEntry for a given query
Symbol * symbol; ///< The Symbol for a given query
+ Variable * variable; ///< The global variable matching the given query
};
diff --git a/include/lldb/Target/FileAction.h b/include/lldb/Target/FileAction.h
index 228a9e6098c1..4015cbb5ea89 100644
--- a/include/lldb/Target/FileAction.h
+++ b/include/lldb/Target/FileAction.h
@@ -1,4 +1,4 @@
-//===-- ProcessLaunchInfo.h -------------------------------------*- C++ -*-===//
+//===-- FileAction.h --------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/include/lldb/Target/LanguageRuntime.h b/include/lldb/Target/LanguageRuntime.h
index 0aaa67c2382c..d5ed81956475 100644
--- a/include/lldb/Target/LanguageRuntime.h
+++ b/include/lldb/Target/LanguageRuntime.h
@@ -102,6 +102,13 @@ public:
virtual lldb::SearchFilterSP
CreateExceptionSearchFilter ();
+
+ virtual bool
+ GetTypeBitSize (const ClangASTType& clang_type,
+ uint64_t &size)
+ {
+ return false;
+ }
protected:
//------------------------------------------------------------------
diff --git a/include/lldb/Target/ObjCLanguageRuntime.h b/include/lldb/Target/ObjCLanguageRuntime.h
index a3fee91428fa..42a391478e3e 100644
--- a/include/lldb/Target/ObjCLanguageRuntime.h
+++ b/include/lldb/Target/ObjCLanguageRuntime.h
@@ -20,6 +20,7 @@
// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Core/PluginInterface.h"
+#include "lldb/Core/ThreadSafeDenseMap.h"
#include "lldb/Symbol/ClangASTType.h"
#include "lldb/Symbol/DeclVendor.h"
#include "lldb/Symbol/Type.h"
@@ -514,6 +515,10 @@ public:
m_negative_complete_class_cache.clear();
}
+ virtual bool
+ GetTypeBitSize (const ClangASTType& clang_type,
+ uint64_t &size);
+
protected:
//------------------------------------------------------------------
// Classes that inherit from ObjCLanguageRuntime can see and modify these
@@ -610,11 +615,13 @@ private:
typedef std::multimap<uint32_t, ObjCISA> HashToISAMap;
typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator;
typedef HashToISAMap::iterator HashToISAIterator;
+ typedef ThreadSafeDenseMap<void*, uint64_t> TypeSizeCache;
MsgImplMap m_impl_cache;
LazyBool m_has_new_literals_and_indexing;
ISAToDescriptorMap m_isa_to_descriptor;
HashToISAMap m_hash_to_isa_map;
+ TypeSizeCache m_type_size_cache;
protected:
uint32_t m_isa_to_descriptor_stop_id;
diff --git a/include/lldb/Target/Platform.h b/include/lldb/Target/Platform.h
index 8b14cc2a0ece..f4596bd00f0b 100644
--- a/include/lldb/Target/Platform.h
+++ b/include/lldb/Target/Platform.h
@@ -28,7 +28,7 @@
// TODO pull NativeDelegate class out of NativeProcessProtocol so we
// can just forward ref the NativeDelegate rather than include it here.
-#include "../../../source/Host/common/NativeProcessProtocol.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
namespace lldb_private {
@@ -380,6 +380,12 @@ namespace lldb_private {
LaunchProcess (ProcessLaunchInfo &launch_info);
//------------------------------------------------------------------
+ /// Kill process on a platform.
+ //------------------------------------------------------------------
+ virtual Error
+ KillProcess (const lldb::pid_t pid);
+
+ //------------------------------------------------------------------
/// Lets a platform answer if it is compatible with a given
/// architecture and the target triple contained within.
//------------------------------------------------------------------
@@ -569,7 +575,7 @@ namespace lldb_private {
// Appends the platform-specific options required to find the modules for the current platform.
virtual void
- AddClangModuleCompilationOptions (std::vector<std::string> &options);
+ AddClangModuleCompilationOptions (Target *target, std::vector<std::string> &options);
ConstString
GetWorkingDirectory ();
@@ -952,8 +958,7 @@ namespace lldb_private {
uint32_t m_update_os_version;
ArchSpec m_system_arch; // The architecture of the kernel or the remote platform
typedef std::map<uint32_t, ConstString> IDToNameMap;
- Mutex m_uid_map_mutex;
- Mutex m_gid_map_mutex;
+ Mutex m_mutex; // Mutex for modifying Platform data structures that should only be used for non-reentrant code
IDToNameMap m_uid_map;
IDToNameMap m_gid_map;
size_t m_max_uid_name_len;
@@ -967,7 +972,6 @@ namespace lldb_private {
std::string m_local_cache_directory;
std::vector<ConstString> m_trap_handlers;
bool m_calculated_trap_handlers;
- Mutex m_trap_handler_mutex;
//------------------------------------------------------------------
/// Ask the Platform subclass to fill in the list of trap handler names
@@ -988,7 +992,7 @@ namespace lldb_private {
const char *
GetCachedUserName (uint32_t uid)
{
- Mutex::Locker locker (m_uid_map_mutex);
+ Mutex::Locker locker (m_mutex);
IDToNameMap::iterator pos = m_uid_map.find (uid);
if (pos != m_uid_map.end())
{
@@ -1004,7 +1008,7 @@ namespace lldb_private {
const char *
SetCachedUserName (uint32_t uid, const char *name, size_t name_len)
{
- Mutex::Locker locker (m_uid_map_mutex);
+ Mutex::Locker locker (m_mutex);
ConstString const_name (name);
m_uid_map[uid] = const_name;
if (m_max_uid_name_len < name_len)
@@ -1016,7 +1020,7 @@ namespace lldb_private {
void
SetUserNameNotFound (uint32_t uid)
{
- Mutex::Locker locker (m_uid_map_mutex);
+ Mutex::Locker locker (m_mutex);
m_uid_map[uid] = ConstString();
}
@@ -1024,14 +1028,14 @@ namespace lldb_private {
void
ClearCachedUserNames ()
{
- Mutex::Locker locker (m_uid_map_mutex);
+ Mutex::Locker locker (m_mutex);
m_uid_map.clear();
}
const char *
GetCachedGroupName (uint32_t gid)
{
- Mutex::Locker locker (m_gid_map_mutex);
+ Mutex::Locker locker (m_mutex);
IDToNameMap::iterator pos = m_gid_map.find (gid);
if (pos != m_gid_map.end())
{
@@ -1047,7 +1051,7 @@ namespace lldb_private {
const char *
SetCachedGroupName (uint32_t gid, const char *name, size_t name_len)
{
- Mutex::Locker locker (m_gid_map_mutex);
+ Mutex::Locker locker (m_mutex);
ConstString const_name (name);
m_gid_map[gid] = const_name;
if (m_max_gid_name_len < name_len)
@@ -1059,14 +1063,14 @@ namespace lldb_private {
void
SetGroupNameNotFound (uint32_t gid)
{
- Mutex::Locker locker (m_gid_map_mutex);
+ Mutex::Locker locker (m_mutex);
m_gid_map[gid] = ConstString();
}
void
ClearCachedGroupNames ()
{
- Mutex::Locker locker (m_gid_map_mutex);
+ Mutex::Locker locker (m_mutex);
m_gid_map.clear();
}
diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h
index e04de511c797..6608391b94fd 100644
--- a/include/lldb/Target/Process.h
+++ b/include/lldb/Target/Process.h
@@ -678,13 +678,16 @@ public:
bool
IsLastResumeForUserExpression () const
{
+ // If we haven't yet resumed the target, then it can't be for a user expression...
+ if (m_resume_id == 0)
+ return false;
+
return m_resume_id == m_last_user_expression_resume;
}
void
SetRunningUserExpression (bool on)
{
- // REMOVEME printf ("Setting running user expression %s at resume id %d - value: %d.\n", on ? "on" : "off", m_resume_id, m_running_user_expression);
if (on)
m_running_user_expression++;
else
@@ -3177,6 +3180,7 @@ protected:
lldb::IOHandlerSP m_process_input_reader;
Communication m_stdio_communication;
Mutex m_stdio_communication_mutex;
+ bool m_stdio_disable; /// Remember process launch setting
std::string m_stdout_data;
std::string m_stderr_data;
Mutex m_profile_data_comm_mutex;
diff --git a/include/lldb/Utility/AnsiTerminal.h b/include/lldb/Utility/AnsiTerminal.h
index 036950c1bd45..9a5117ae74ea 100644
--- a/include/lldb/Utility/AnsiTerminal.h
+++ b/include/lldb/Utility/AnsiTerminal.h
@@ -50,37 +50,6 @@
namespace lldb_utility {
namespace ansi {
- const char *k_escape_start = "\033[";
- const char *k_escape_end = "m";
-
- const char *k_fg_black = "30";
- const char *k_fg_red = "31";
- const char *k_fg_green = "32";
- const char *k_fg_yellow = "33";
- const char *k_fg_blue = "34";
- const char *k_fg_purple = "35";
- const char *k_fg_cyan = "36";
- const char *k_fg_white = "37";
-
- const char *k_bg_black = "40";
- const char *k_bg_red = "41";
- const char *k_bg_green = "42";
- const char *k_bg_yellow = "43";
- const char *k_bg_blue = "44";
- const char *k_bg_purple = "45";
- const char *k_bg_cyan = "46";
- const char *k_bg_white = "47";
-
- const char *k_ctrl_normal = "0";
- const char *k_ctrl_bold = "1";
- const char *k_ctrl_faint = "2";
- const char *k_ctrl_italic = "3";
- const char *k_ctrl_underline = "4";
- const char *k_ctrl_slow_blink = "5";
- const char *k_ctrl_fast_blink = "6";
- const char *k_ctrl_negative = "7";
- const char *k_ctrl_conceal = "8";
- const char *k_ctrl_crossed_out = "9";
inline std::string
FormatAnsiTerminalCodes(const char *format, bool do_color = true)
diff --git a/include/lldb/Utility/ProcessStructReader.h b/include/lldb/Utility/ProcessStructReader.h
index 7b05d93151aa..d053b702462e 100644
--- a/include/lldb/Utility/ProcessStructReader.h
+++ b/include/lldb/Utility/ProcessStructReader.h
@@ -59,7 +59,7 @@ namespace lldb_private {
// no support for bitfields in here (yet)
if (is_bitfield)
return;
- auto size = field_type.GetByteSize();
+ auto size = field_type.GetByteSize(nullptr);
// no support for things larger than a uint64_t (yet)
if (size > 8)
return;
@@ -67,7 +67,7 @@ namespace lldb_private {
size_t byte_index = static_cast<size_t>(bit_offset / 8);
m_fields[const_name] = FieldImpl{field_type, byte_index, static_cast<size_t>(size)};
}
- size_t total_size = struct_type.GetByteSize();
+ size_t total_size = struct_type.GetByteSize(nullptr);
lldb::DataBufferSP buffer_sp(new DataBufferHeap(total_size,0));
Error error;
process->ReadMemoryFromInferior(base_addr,
diff --git a/include/lldb/lldb-enumerations.h b/include/lldb/lldb-enumerations.h
index 87ee14875734..f70ee0cd7b28 100644
--- a/include/lldb/lldb-enumerations.h
+++ b/include/lldb/lldb-enumerations.h
@@ -290,7 +290,11 @@ namespace lldb {
eSymbolContextBlock = (1u << 4), ///< Set when the deepest \a block is requested from a query, or was located in query results
eSymbolContextLineEntry = (1u << 5), ///< Set when \a line_entry is requested from a query, or was located in query results
eSymbolContextSymbol = (1u << 6), ///< Set when \a symbol is requested from a query, or was located in query results
- eSymbolContextEverything = ((eSymbolContextSymbol << 1) - 1u) ///< Indicates to try and lookup everything up during a query.
+ eSymbolContextEverything = ((eSymbolContextSymbol << 1) - 1u), ///< Indicates to try and lookup everything up during a routine symbol context query.
+ eSymbolContextVariable = (1u << 7) ///< Set when \a 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.
} SymbolContextItem;
typedef enum Permissions
@@ -374,6 +378,8 @@ namespace lldb {
eLanguageTypeUPC = 0x0012, ///< Unified Parallel C.
eLanguageTypeD = 0x0013, ///< D.
eLanguageTypePython = 0x0014, ///< Python.
+ // NOTE: The below are DWARF5 constants, subject to change upon
+ // completion of the DWARF5 specification
eLanguageTypeOpenCL = 0x0015, ///< OpenCL.
eLanguageTypeGo = 0x0016, ///< Go.
eLanguageTypeModula3 = 0x0017, ///< Modula 3.
@@ -386,6 +392,9 @@ namespace lldb {
eLanguageTypeSwift = 0x001e, ///< Swift.
eLanguageTypeJulia = 0x001f, ///< Julia.
eLanguageTypeDylan = 0x0020, ///< Dylan.
+ eLanguageTypeC_plus_plus_14 = 0x0021, ///< ISO C++:2014.
+ eLanguageTypeFortran03 = 0x0022, ///< ISO Fortran 2003.
+ eLanguageTypeFortran08 = 0x0023, ///< ISO Fortran 2008.
eNumLanguageTypes
} LanguageType;
diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h
index 1ecb2f179bb2..53f59dd62096 100644
--- a/include/lldb/lldb-forward.h
+++ b/include/lldb/lldb-forward.h
@@ -146,6 +146,7 @@ class OptionValueEnumeration;
class OptionValueFileSpec;
class OptionValueFileSpecList;
class OptionValueFormat;
+class OptionValueFormatEntity;
class OptionValuePathMappings;
class OptionValueProperties;
class OptionValueRegex;
diff --git a/source/API/SBInstruction.cpp b/source/API/SBInstruction.cpp
index eccc4e29aadf..6158418d2f2a 100644
--- a/source/API/SBInstruction.cpp
+++ b/source/API/SBInstruction.cpp
@@ -178,8 +178,9 @@ SBInstruction::GetDescription (lldb::SBStream &s)
module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
// Use the "ref()" instead of the "get()" accessor in case the SBStream
// didn't have a stream already created, one will get created...
- const char *disassemble_format = "${addr-file-or-load}: ";
- m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL, &sc, NULL, disassemble_format);
+ FormatEntity::Entry format;
+ FormatEntity::Parse("${addr}: ", format);
+ m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL, &sc, NULL, &format);
return true;
}
return false;
@@ -199,8 +200,9 @@ SBInstruction::Print (FILE *out)
if (module_sp)
module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
StreamFile out_stream (out, false);
- const char *disassemble_format = "${addr-file-or-load}: ";
- m_opaque_sp->Dump (&out_stream, 0, true, false, NULL, &sc, NULL, disassemble_format);
+ FormatEntity::Entry format;
+ FormatEntity::Parse("${addr}: ", format);
+ m_opaque_sp->Dump (&out_stream, 0, true, false, NULL, &sc, NULL, &format);
}
}
diff --git a/source/API/SBInstructionList.cpp b/source/API/SBInstructionList.cpp
index 31585b3e6868..812824b4d2e5 100644
--- a/source/API/SBInstructionList.cpp
+++ b/source/API/SBInstructionList.cpp
@@ -102,7 +102,8 @@ SBInstructionList::GetDescription (lldb::SBStream &description)
// exist already inside description...
Stream &sref = description.ref();
const uint32_t max_opcode_byte_size = m_opaque_sp->GetInstructionList().GetMaxOpcocdeByteSize();
- const char *disassemble_format = "${addr-file-or-load}: ";
+ FormatEntity::Entry format;
+ FormatEntity::Parse("${addr}: ", format);
SymbolContext sc;
SymbolContext prev_sc;
for (size_t i=0; i<num_instructions; ++i)
@@ -119,7 +120,7 @@ SBInstructionList::GetDescription (lldb::SBStream &description)
module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
}
- inst->Dump (&sref, max_opcode_byte_size, true, false, NULL, &sc, &prev_sc, disassemble_format);
+ inst->Dump (&sref, max_opcode_byte_size, true, false, NULL, &sc, &prev_sc, &format);
sref.EOL();
}
return true;
diff --git a/source/API/SBLaunchInfo.cpp b/source/API/SBLaunchInfo.cpp
new file mode 100644
index 000000000000..dcb0e1b488ba
--- /dev/null
+++ b/source/API/SBLaunchInfo.cpp
@@ -0,0 +1,278 @@
+//===-- SBLaunchInfo.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/API/SBLaunchInfo.h"
+
+#include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBListener.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBLaunchInfo::SBLaunchInfo (const char **argv) :
+ m_opaque_sp(new ProcessLaunchInfo())
+{
+ m_opaque_sp->GetFlags().Reset (eLaunchFlagDebug | eLaunchFlagDisableASLR);
+ if (argv && argv[0])
+ m_opaque_sp->GetArguments().SetArguments(argv);
+}
+
+SBLaunchInfo::~SBLaunchInfo()
+{
+}
+
+lldb_private::ProcessLaunchInfo &
+SBLaunchInfo::ref ()
+{
+ return *m_opaque_sp;
+}
+
+lldb::pid_t
+SBLaunchInfo::GetProcessID()
+{
+ return m_opaque_sp->GetProcessID();
+}
+
+uint32_t
+SBLaunchInfo::GetUserID()
+{
+ return m_opaque_sp->GetUserID();
+}
+
+uint32_t
+SBLaunchInfo::GetGroupID()
+{
+ return m_opaque_sp->GetGroupID();
+}
+
+bool
+SBLaunchInfo::UserIDIsValid ()
+{
+ return m_opaque_sp->UserIDIsValid();
+}
+
+bool
+SBLaunchInfo::GroupIDIsValid ()
+{
+ return m_opaque_sp->GroupIDIsValid();
+}
+
+void
+SBLaunchInfo::SetUserID (uint32_t uid)
+{
+ m_opaque_sp->SetUserID (uid);
+}
+
+void
+SBLaunchInfo::SetGroupID (uint32_t gid)
+{
+ m_opaque_sp->SetGroupID (gid);
+}
+
+SBFileSpec
+SBLaunchInfo::GetExecutableFile ()
+{
+ return SBFileSpec (m_opaque_sp->GetExecutableFile());
+}
+
+void
+SBLaunchInfo::SetExecutableFile (SBFileSpec exe_file, bool add_as_first_arg)
+{
+ m_opaque_sp->SetExecutableFile(exe_file.ref(), add_as_first_arg);
+}
+
+SBListener
+SBLaunchInfo::GetListener ()
+{
+ return SBListener(m_opaque_sp->GetListener());
+}
+
+void
+SBLaunchInfo::SetListener (SBListener &listener)
+{
+ m_opaque_sp->SetListener(listener.GetSP());
+}
+
+uint32_t
+SBLaunchInfo::GetNumArguments ()
+{
+ return m_opaque_sp->GetArguments().GetArgumentCount();
+}
+
+const char *
+SBLaunchInfo::GetArgumentAtIndex (uint32_t idx)
+{
+ return m_opaque_sp->GetArguments().GetArgumentAtIndex(idx);
+}
+
+void
+SBLaunchInfo::SetArguments (const char **argv, bool append)
+{
+ if (append)
+ {
+ if (argv)
+ m_opaque_sp->GetArguments().AppendArguments(argv);
+ }
+ else
+ {
+ if (argv)
+ m_opaque_sp->GetArguments().SetArguments(argv);
+ else
+ m_opaque_sp->GetArguments().Clear();
+ }
+}
+
+uint32_t
+SBLaunchInfo::GetNumEnvironmentEntries ()
+{
+ return m_opaque_sp->GetEnvironmentEntries().GetArgumentCount();
+}
+
+const char *
+SBLaunchInfo::GetEnvironmentEntryAtIndex (uint32_t idx)
+{
+ return m_opaque_sp->GetEnvironmentEntries().GetArgumentAtIndex(idx);
+}
+
+void
+SBLaunchInfo::SetEnvironmentEntries (const char **envp, bool append)
+{
+ if (append)
+ {
+ if (envp)
+ m_opaque_sp->GetEnvironmentEntries().AppendArguments(envp);
+ }
+ else
+ {
+ if (envp)
+ m_opaque_sp->GetEnvironmentEntries().SetArguments(envp);
+ else
+ m_opaque_sp->GetEnvironmentEntries().Clear();
+ }
+}
+
+void
+SBLaunchInfo::Clear ()
+{
+ m_opaque_sp->Clear();
+}
+
+const char *
+SBLaunchInfo::GetWorkingDirectory () const
+{
+ return m_opaque_sp->GetWorkingDirectory();
+}
+
+void
+SBLaunchInfo::SetWorkingDirectory (const char *working_dir)
+{
+ m_opaque_sp->SetWorkingDirectory(working_dir);
+}
+
+uint32_t
+SBLaunchInfo::GetLaunchFlags ()
+{
+ return m_opaque_sp->GetFlags().Get();
+}
+
+void
+SBLaunchInfo::SetLaunchFlags (uint32_t flags)
+{
+ m_opaque_sp->GetFlags().Reset(flags);
+}
+
+const char *
+SBLaunchInfo::GetProcessPluginName ()
+{
+ return m_opaque_sp->GetProcessPluginName();
+}
+
+void
+SBLaunchInfo::SetProcessPluginName (const char *plugin_name)
+{
+ return m_opaque_sp->SetProcessPluginName (plugin_name);
+}
+
+const char *
+SBLaunchInfo::GetShell ()
+{
+ // Constify this string so that it is saved in the string pool. Otherwise
+ // it would be freed when this function goes out of scope.
+ ConstString shell(m_opaque_sp->GetShell().GetPath().c_str());
+ return shell.AsCString();
+}
+
+void
+SBLaunchInfo::SetShell (const char * path)
+{
+ m_opaque_sp->SetShell (FileSpec(path, false));
+}
+
+uint32_t
+SBLaunchInfo::GetResumeCount ()
+{
+ return m_opaque_sp->GetResumeCount();
+}
+
+void
+SBLaunchInfo::SetResumeCount (uint32_t c)
+{
+ m_opaque_sp->SetResumeCount (c);
+}
+
+bool
+SBLaunchInfo::AddCloseFileAction (int fd)
+{
+ return m_opaque_sp->AppendCloseFileAction(fd);
+}
+
+bool
+SBLaunchInfo::AddDuplicateFileAction (int fd, int dup_fd)
+{
+ return m_opaque_sp->AppendDuplicateFileAction(fd, dup_fd);
+}
+
+bool
+SBLaunchInfo::AddOpenFileAction (int fd, const char *path, bool read, bool write)
+{
+ return m_opaque_sp->AppendOpenFileAction(fd, path, read, write);
+}
+
+bool
+SBLaunchInfo::AddSuppressFileAction (int fd, bool read, bool write)
+{
+ return m_opaque_sp->AppendSuppressFileAction(fd, read, write);
+}
+
+void
+SBLaunchInfo::SetLaunchEventData (const char *data)
+{
+ m_opaque_sp->SetLaunchEventData (data);
+}
+
+const char *
+SBLaunchInfo::GetLaunchEventData () const
+{
+ return m_opaque_sp->GetLaunchEventData ();
+}
+
+void
+SBLaunchInfo::SetDetachOnError (bool enable)
+{
+ m_opaque_sp->SetDetachOnError (enable);
+}
+
+bool
+SBLaunchInfo::GetDetachOnError () const
+{
+ return m_opaque_sp->GetDetachOnError ();
+}
diff --git a/source/API/SBPlatform.cpp b/source/API/SBPlatform.cpp
index d3e769ae675b..b23891d39c21 100644
--- a/source/API/SBPlatform.cpp
+++ b/source/API/SBPlatform.cpp
@@ -10,6 +10,7 @@
#include "lldb/API/SBPlatform.h"
#include "lldb/API/SBError.h"
#include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBLaunchInfo.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Error.h"
#include "lldb/Host/File.h"
@@ -17,6 +18,8 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Platform.h"
+#include <functional>
+
using namespace lldb;
using namespace lldb_private;
@@ -484,104 +487,108 @@ SBError
SBPlatform::Put (SBFileSpec &src,
SBFileSpec &dst)
{
- SBError sb_error;
-
- PlatformSP platform_sp(GetSP());
- if (platform_sp)
- {
- if (src.Exists())
+ return ExecuteConnected(
+ [&](const lldb::PlatformSP& platform_sp)
+ {
+ if (src.Exists())
+ {
+ uint32_t permissions = src.ref().GetPermissions();
+ if (permissions == 0)
+ {
+ if (src.ref().GetFileType() == FileSpec::eFileTypeDirectory)
+ permissions = eFilePermissionsDirectoryDefault;
+ else
+ permissions = eFilePermissionsFileDefault;
+ }
+
+ return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
+ }
+
+ Error error;
+ error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
+ return error;
+ });
+}
+
+SBError
+SBPlatform::Install (SBFileSpec &src,
+ SBFileSpec &dst)
+{
+ return ExecuteConnected(
+ [&](const lldb::PlatformSP& platform_sp)
+ {
+ if (src.Exists())
+ return platform_sp->Install(src.ref(), dst.ref());
+
+ Error error;
+ error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
+ return error;
+ });
+}
+
+
+SBError
+SBPlatform::Run (SBPlatformShellCommand &shell_command)
+{
+ return ExecuteConnected(
+ [&](const lldb::PlatformSP& platform_sp)
{
- uint32_t permissions = src.ref().GetPermissions();
- if (permissions == 0)
+ const char *command = shell_command.GetCommand();
+ if (!command)
+ return Error("invalid shell command (empty)");
+
+ const char *working_dir = shell_command.GetWorkingDirectory();
+ if (working_dir == NULL)
{
- if (src.ref().GetFileType() == FileSpec::eFileTypeDirectory)
- permissions = eFilePermissionsDirectoryDefault;
- else
- permissions = eFilePermissionsFileDefault;
+ working_dir = platform_sp->GetWorkingDirectory().GetCString();
+ if (working_dir)
+ shell_command.SetWorkingDirectory(working_dir);
}
+ return platform_sp->RunShellCommand(command,
+ 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_sec);
+ });
+}
- sb_error.ref() = platform_sp->PutFile(src.ref(),
- dst.ref(),
- permissions);
- }
- else
+SBError
+SBPlatform::Launch (SBLaunchInfo &launch_info)
+{
+ return ExecuteConnected(
+ [&](const lldb::PlatformSP& platform_sp)
{
- sb_error.ref().SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
- }
- }
- else
- {
- sb_error.SetErrorString("invalid platform");
- }
- return sb_error;
+ return platform_sp->LaunchProcess(launch_info.ref());
+ });
}
SBError
-SBPlatform::Install (SBFileSpec &src,
- SBFileSpec &dst)
+SBPlatform::Kill (const lldb::pid_t pid)
{
- SBError sb_error;
- PlatformSP platform_sp(GetSP());
- if (platform_sp)
- {
- if (src.Exists())
- {
- sb_error.ref() = platform_sp->Install(src.ref(), dst.ref());
- }
- else
+ return ExecuteConnected(
+ [&](const lldb::PlatformSP& platform_sp)
{
- sb_error.ref().SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
- }
- }
- else
- {
- sb_error.SetErrorString("invalid platform");
- }
- return sb_error;
+ return platform_sp->KillProcess(pid);
+ });
}
-
SBError
-SBPlatform::Run (SBPlatformShellCommand &shell_command)
+SBPlatform::ExecuteConnected (const std::function<Error(const lldb::PlatformSP&)>& func)
{
SBError sb_error;
- PlatformSP platform_sp(GetSP());
+ const auto platform_sp(GetSP());
if (platform_sp)
{
if (platform_sp->IsConnected())
- {
- const char *command = shell_command.GetCommand();
- if (command)
- {
- const char *working_dir = shell_command.GetWorkingDirectory();
- if (working_dir == NULL)
- {
- working_dir = platform_sp->GetWorkingDirectory().GetCString();
- if (working_dir)
- shell_command.SetWorkingDirectory(working_dir);
- }
- sb_error.ref() = platform_sp->RunShellCommand(command,
- 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_sec);
- }
- else
- {
- sb_error.SetErrorString("invalid shell command (empty)");
- }
- }
+ sb_error.ref() = func(platform_sp);
else
- {
sb_error.SetErrorString("not connected");
- }
}
else
- {
sb_error.SetErrorString("invalid platform");
- }
- return sb_error;
+
+ return sb_error;
}
SBError
diff --git a/source/API/SBStream.cpp b/source/API/SBStream.cpp
index f5b5c08411c7..f50334f74189 100644
--- a/source/API/SBStream.cpp
+++ b/source/API/SBStream.cpp
@@ -70,6 +70,9 @@ SBStream::Printf (const char *format, ...)
void
SBStream::RedirectToFile (const char *path, bool append)
{
+ if (path == nullptr)
+ return;
+
std::string local_data;
if (m_opaque_ap.get())
{
@@ -104,6 +107,9 @@ SBStream::RedirectToFile (const char *path, bool append)
void
SBStream::RedirectToFileHandle (FILE *fh, bool transfer_fh_ownership)
{
+ if (fh == nullptr)
+ return;
+
std::string local_data;
if (m_opaque_ap.get())
{
diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp
index b87b1acf45df..b13d8289560f 100644
--- a/source/API/SBTarget.cpp
+++ b/source/API/SBTarget.cpp
@@ -66,259 +66,6 @@ using namespace lldb_private;
#define DEFAULT_DISASM_BYTE_SIZE 32
-SBLaunchInfo::SBLaunchInfo (const char **argv) :
- m_opaque_sp(new ProcessLaunchInfo())
-{
- m_opaque_sp->GetFlags().Reset (eLaunchFlagDebug | eLaunchFlagDisableASLR);
- if (argv && argv[0])
- m_opaque_sp->GetArguments().SetArguments(argv);
-}
-
-SBLaunchInfo::~SBLaunchInfo()
-{
-}
-
-lldb_private::ProcessLaunchInfo &
-SBLaunchInfo::ref ()
-{
- return *m_opaque_sp;
-}
-
-
-uint32_t
-SBLaunchInfo::GetUserID()
-{
- return m_opaque_sp->GetUserID();
-}
-
-uint32_t
-SBLaunchInfo::GetGroupID()
-{
- return m_opaque_sp->GetGroupID();
-}
-
-bool
-SBLaunchInfo::UserIDIsValid ()
-{
- return m_opaque_sp->UserIDIsValid();
-}
-
-bool
-SBLaunchInfo::GroupIDIsValid ()
-{
- return m_opaque_sp->GroupIDIsValid();
-}
-
-void
-SBLaunchInfo::SetUserID (uint32_t uid)
-{
- m_opaque_sp->SetUserID (uid);
-}
-
-void
-SBLaunchInfo::SetGroupID (uint32_t gid)
-{
- m_opaque_sp->SetGroupID (gid);
-}
-
-SBFileSpec
-SBLaunchInfo::GetExecutableFile ()
-{
- return SBFileSpec (m_opaque_sp->GetExecutableFile());
-}
-
-void
-SBLaunchInfo::SetExecutableFile (SBFileSpec exe_file, bool add_as_first_arg)
-{
- m_opaque_sp->SetExecutableFile(exe_file.ref(), add_as_first_arg);
-}
-
-SBListener
-SBLaunchInfo::GetListener ()
-{
- return SBListener(m_opaque_sp->GetListener());
-}
-
-void
-SBLaunchInfo::SetListener (SBListener &listener)
-{
- m_opaque_sp->SetListener(listener.GetSP());
-}
-
-uint32_t
-SBLaunchInfo::GetNumArguments ()
-{
- return m_opaque_sp->GetArguments().GetArgumentCount();
-}
-
-const char *
-SBLaunchInfo::GetArgumentAtIndex (uint32_t idx)
-{
- return m_opaque_sp->GetArguments().GetArgumentAtIndex(idx);
-}
-
-void
-SBLaunchInfo::SetArguments (const char **argv, bool append)
-{
- if (append)
- {
- if (argv)
- m_opaque_sp->GetArguments().AppendArguments(argv);
- }
- else
- {
- if (argv)
- m_opaque_sp->GetArguments().SetArguments(argv);
- else
- m_opaque_sp->GetArguments().Clear();
- }
-}
-
-uint32_t
-SBLaunchInfo::GetNumEnvironmentEntries ()
-{
- return m_opaque_sp->GetEnvironmentEntries().GetArgumentCount();
-}
-
-const char *
-SBLaunchInfo::GetEnvironmentEntryAtIndex (uint32_t idx)
-{
- return m_opaque_sp->GetEnvironmentEntries().GetArgumentAtIndex(idx);
-}
-
-void
-SBLaunchInfo::SetEnvironmentEntries (const char **envp, bool append)
-{
- if (append)
- {
- if (envp)
- m_opaque_sp->GetEnvironmentEntries().AppendArguments(envp);
- }
- else
- {
- if (envp)
- m_opaque_sp->GetEnvironmentEntries().SetArguments(envp);
- else
- m_opaque_sp->GetEnvironmentEntries().Clear();
- }
-}
-
-void
-SBLaunchInfo::Clear ()
-{
- m_opaque_sp->Clear();
-}
-
-const char *
-SBLaunchInfo::GetWorkingDirectory () const
-{
- return m_opaque_sp->GetWorkingDirectory();
-}
-
-void
-SBLaunchInfo::SetWorkingDirectory (const char *working_dir)
-{
- m_opaque_sp->SetWorkingDirectory(working_dir);
-}
-
-uint32_t
-SBLaunchInfo::GetLaunchFlags ()
-{
- return m_opaque_sp->GetFlags().Get();
-}
-
-void
-SBLaunchInfo::SetLaunchFlags (uint32_t flags)
-{
- m_opaque_sp->GetFlags().Reset(flags);
-}
-
-const char *
-SBLaunchInfo::GetProcessPluginName ()
-{
- return m_opaque_sp->GetProcessPluginName();
-}
-
-void
-SBLaunchInfo::SetProcessPluginName (const char *plugin_name)
-{
- return m_opaque_sp->SetProcessPluginName (plugin_name);
-}
-
-const char *
-SBLaunchInfo::GetShell ()
-{
- // Constify this string so that it is saved in the string pool. Otherwise
- // it would be freed when this function goes out of scope.
- ConstString shell(m_opaque_sp->GetShell().GetPath().c_str());
- return shell.AsCString();
-}
-
-void
-SBLaunchInfo::SetShell (const char * path)
-{
- m_opaque_sp->SetShell (FileSpec(path, false));
-}
-
-uint32_t
-SBLaunchInfo::GetResumeCount ()
-{
- return m_opaque_sp->GetResumeCount();
-}
-
-void
-SBLaunchInfo::SetResumeCount (uint32_t c)
-{
- m_opaque_sp->SetResumeCount (c);
-}
-
-bool
-SBLaunchInfo::AddCloseFileAction (int fd)
-{
- return m_opaque_sp->AppendCloseFileAction(fd);
-}
-
-bool
-SBLaunchInfo::AddDuplicateFileAction (int fd, int dup_fd)
-{
- return m_opaque_sp->AppendDuplicateFileAction(fd, dup_fd);
-}
-
-bool
-SBLaunchInfo::AddOpenFileAction (int fd, const char *path, bool read, bool write)
-{
- return m_opaque_sp->AppendOpenFileAction(fd, path, read, write);
-}
-
-bool
-SBLaunchInfo::AddSuppressFileAction (int fd, bool read, bool write)
-{
- return m_opaque_sp->AppendSuppressFileAction(fd, read, write);
-}
-
-void
-SBLaunchInfo::SetLaunchEventData (const char *data)
-{
- m_opaque_sp->SetLaunchEventData (data);
-}
-
-const char *
-SBLaunchInfo::GetLaunchEventData () const
-{
- return m_opaque_sp->GetLaunchEventData ();
-}
-
-void
-SBLaunchInfo::SetDetachOnError (bool enable)
-{
- m_opaque_sp->SetDetachOnError (enable);
-}
-
-bool
-SBLaunchInfo::GetDetachOnError () const
-{
- return m_opaque_sp->GetDetachOnError ();
-}
SBAttachInfo::SBAttachInfo () :
m_opaque_sp (new ProcessAttachInfo())
@@ -729,6 +476,9 @@ SBTarget::Launch
{
Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ if (stop_at_entry)
+ launch_flags |= eLaunchFlagStopAtEntry;
+
if (getenv("LLDB_LAUNCH_FLAG_DISABLE_ASLR"))
launch_flags |= eLaunchFlagDisableASLR;
diff --git a/source/API/SBThread.cpp b/source/API/SBThread.cpp
index 6524d10fb705..9fe0d029496c 100644
--- a/source/API/SBThread.cpp
+++ b/source/API/SBThread.cpp
@@ -1491,7 +1491,8 @@ SBThread::GetDescription (SBStream &description) const
ExecutionContext exe_ctx (m_opaque_sp.get());
if (exe_ctx.HasThreadScope())
{
- strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
+ exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, LLDB_INVALID_THREAD_ID);
+ //strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
}
else
strm.PutCString ("No value");
diff --git a/source/API/SBType.cpp b/source/API/SBType.cpp
index 8a0f5d848a3d..31a4eba8bf33 100644
--- a/source/API/SBType.cpp
+++ b/source/API/SBType.cpp
@@ -143,7 +143,7 @@ SBType::GetByteSize()
if (!IsValid())
return 0;
- return m_opaque_sp->GetClangASTType(false).GetByteSize();
+ return m_opaque_sp->GetClangASTType(false).GetByteSize(nullptr);
}
@@ -164,6 +164,14 @@ SBType::IsArrayType()
}
bool
+SBType::IsVectorType()
+{
+ if (!IsValid())
+ return false;
+ return m_opaque_sp->GetClangASTType(true).IsVectorType(nullptr, nullptr);
+}
+
+bool
SBType::IsReferenceType()
{
if (!IsValid())
@@ -220,7 +228,20 @@ SBType::GetArrayElementType()
return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetClangASTType(true).GetArrayElementType())));
}
-bool
+SBType
+SBType::GetVectorElementType ()
+{
+ SBType type_sb;
+ if (IsValid())
+ {
+ ClangASTType vector_element_type;
+ if (m_opaque_sp->GetClangASTType(true).IsVectorType(&vector_element_type, nullptr))
+ type_sb.SetSP(TypeImplSP(new TypeImpl(vector_element_type)));
+ }
+ return type_sb;
+}
+
+bool
SBType::IsFunctionType ()
{
if (!IsValid())
diff --git a/source/API/SBTypeCategory.cpp b/source/API/SBTypeCategory.cpp
index 9fe4dad01a9f..66cf46236c65 100644
--- a/source/API/SBTypeCategory.cpp
+++ b/source/API/SBTypeCategory.cpp
@@ -353,7 +353,7 @@ SBTypeCategory::AddTypeSummary (SBTypeNameSpecifier type_name,
// this should eventually be fixed by deciding a final location in the LLDB object space for formatters
if (summary.IsFunctionCode())
{
- void *name_token = (void*)ConstString(type_name.GetName()).GetCString();
+ const void *name_token = (const void*)ConstString(type_name.GetName()).GetCString();
const char* script = summary.GetData();
StringList input; input.SplitIntoLines(script, strlen(script));
uint32_t num_debuggers = lldb_private::Debugger::GetNumDebuggers();
@@ -461,7 +461,7 @@ SBTypeCategory::AddTypeSynthetic (SBTypeNameSpecifier type_name,
// this should eventually be fixed by deciding a final location in the LLDB object space for formatters
if (synth.IsClassCode())
{
- void *name_token = (void*)ConstString(type_name.GetName()).GetCString();
+ const void *name_token = (const void*)ConstString(type_name.GetName()).GetCString();
const char* script = synth.GetData();
StringList input; input.SplitIntoLines(script, strlen(script));
uint32_t num_debuggers = lldb_private::Debugger::GetNumDebuggers();
diff --git a/source/API/SBValue.cpp b/source/API/SBValue.cpp
index 0d3d7ad956ee..edecb93944ad 100644
--- a/source/API/SBValue.cpp
+++ b/source/API/SBValue.cpp
@@ -608,7 +608,8 @@ SBValue::GetValueDidChange ()
lldb::ValueObjectSP value_sp(GetSP(locker));
if (value_sp)
{
- result = value_sp->GetValueDidChange ();
+ if (value_sp->UpdateValueIfNeeded(false))
+ result = value_sp->GetValueDidChange ();
}
if (log)
log->Printf ("SBValue(%p)::GetValueDidChange() => %i",
diff --git a/source/Breakpoint/Breakpoint.cpp b/source/Breakpoint/Breakpoint.cpp
index bc269cdb95ac..beb0f6bc5a6e 100644
--- a/source/Breakpoint/Breakpoint.cpp
+++ b/source/Breakpoint/Breakpoint.cpp
@@ -60,7 +60,8 @@ Breakpoint::Breakpoint(Target &target,
m_resolver_sp (resolver_sp),
m_options (),
m_locations (*this),
- m_resolve_indirect_symbols(resolve_indirect_symbols)
+ m_resolve_indirect_symbols(resolve_indirect_symbols),
+ m_hit_count(0)
{
m_being_created = false;
}
@@ -72,7 +73,8 @@ Breakpoint::Breakpoint (Target &new_target, Breakpoint &source_bp) :
m_name_list (source_bp.m_name_list),
m_options (source_bp.m_options),
m_locations(*this),
- m_resolve_indirect_symbols(source_bp.m_resolve_indirect_symbols)
+ m_resolve_indirect_symbols(source_bp.m_resolve_indirect_symbols),
+ m_hit_count(0)
{
// Now go through and copy the filter & resolver:
m_resolver_sp = source_bp.m_resolver_sp->CopyForBreakpoint(*this);
@@ -207,7 +209,7 @@ Breakpoint::IgnoreCountShouldStop ()
uint32_t
Breakpoint::GetHitCount () const
{
- return m_locations.GetHitCount();
+ return m_hit_count;
}
bool
diff --git a/source/Breakpoint/BreakpointLocation.cpp b/source/Breakpoint/BreakpointLocation.cpp
index 11ecfecc5bc7..85233c9374cb 100644
--- a/source/Breakpoint/BreakpointLocation.cpp
+++ b/source/Breakpoint/BreakpointLocation.cpp
@@ -477,7 +477,22 @@ void
BreakpointLocation::BumpHitCount()
{
if (IsEnabled())
+ {
+ // Step our hit count, and also step the hit count of the owner.
IncrementHitCount();
+ m_owner.IncrementHitCount();
+ }
+}
+
+void
+BreakpointLocation::UndoBumpHitCount()
+{
+ if (IsEnabled())
+ {
+ // Step our hit count, and also step the hit count of the owner.
+ DecrementHitCount();
+ m_owner.DecrementHitCount();
+ }
}
bool
diff --git a/source/Breakpoint/StoppointLocation.cpp b/source/Breakpoint/StoppointLocation.cpp
index 9d8d9241253a..35e5979bd9e7 100644
--- a/source/Breakpoint/StoppointLocation.cpp
+++ b/source/Breakpoint/StoppointLocation.cpp
@@ -46,3 +46,10 @@ StoppointLocation::StoppointLocation (break_id_t bid, addr_t addr, uint32_t byte
StoppointLocation::~StoppointLocation()
{
}
+
+void
+StoppointLocation::DecrementHitCount ()
+{
+ assert (m_hit_count > 0);
+ --m_hit_count;
+}
diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp
index 3d4b3aff6fff..025524b3b9a5 100644
--- a/source/Commands/CommandObjectBreakpoint.cpp
+++ b/source/Commands/CommandObjectBreakpoint.cpp
@@ -19,6 +19,7 @@
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/OptionValueString.h"
#include "lldb/Interpreter/OptionValueUInt64.h"
@@ -140,7 +141,7 @@ public:
break;
case 'C':
- m_column = Args::StringToUInt32 (option_arg, 0);
+ m_column = StringConvert::ToUInt32 (option_arg, 0);
break;
case 'c':
@@ -166,6 +167,7 @@ public:
case eLanguageTypeC_plus_plus:
case eLanguageTypeC_plus_plus_03:
case eLanguageTypeC_plus_plus_11:
+ case eLanguageTypeC_plus_plus_14:
m_language = eLanguageTypeC_plus_plus;
break;
case eLanguageTypeObjC:
@@ -207,7 +209,7 @@ public:
case 'i':
{
- m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
+ m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
if (m_ignore_count == UINT32_MAX)
error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
break;
@@ -229,7 +231,7 @@ public:
break;
case 'l':
- m_line_num = Args::StringToUInt32 (option_arg, 0);
+ m_line_num = StringConvert::ToUInt32 (option_arg, 0);
break;
case 'M':
@@ -276,7 +278,7 @@ public:
case 't' :
{
- m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
+ m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
if (m_thread_id == LLDB_INVALID_THREAD_ID)
error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
}
@@ -297,7 +299,7 @@ public:
case 'x':
{
- m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
+ m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
if (m_thread_id == UINT32_MAX)
error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
@@ -838,7 +840,7 @@ public:
break;
case 'i':
{
- m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
+ m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
if (m_ignore_count == UINT32_MAX)
error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
}
@@ -865,7 +867,7 @@ public:
}
else
{
- m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
+ m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
if (m_thread_id == LLDB_INVALID_THREAD_ID)
error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
else
@@ -896,7 +898,7 @@ public:
}
else
{
- m_thread_index = Args::StringToUInt32 (option_arg, UINT32_MAX, 0);
+ m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0);
if (m_thread_id == UINT32_MAX)
error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
else
@@ -1555,7 +1557,7 @@ public:
break;
case 'l':
- m_line_num = Args::StringToUInt32 (option_arg, 0);
+ m_line_num = StringConvert::ToUInt32 (option_arg, 0);
break;
default:
diff --git a/source/Commands/CommandObjectDisassemble.cpp b/source/Commands/CommandObjectDisassemble.cpp
index 8124ce1ef93b..2ba47be1ecf0 100644
--- a/source/Commands/CommandObjectDisassemble.cpp
+++ b/source/Commands/CommandObjectDisassemble.cpp
@@ -19,7 +19,7 @@
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/SourceManager.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -76,13 +76,13 @@ CommandObjectDisassemble::CommandOptions::SetOptionValue (uint32_t option_idx, c
break;
case 'C':
- num_lines_context = Args::StringToUInt32(option_arg, 0, 0, &success);
+ num_lines_context = StringConvert::ToUInt32(option_arg, 0, 0, &success);
if (!success)
error.SetErrorStringWithFormat ("invalid num context lines string: \"%s\"", option_arg);
break;
case 'c':
- num_instructions = Args::StringToUInt32(option_arg, 0, 0, &success);
+ num_instructions = StringConvert::ToUInt32(option_arg, 0, 0, &success);
if (!success)
error.SetErrorStringWithFormat ("invalid num of instructions string: \"%s\"", option_arg);
break;
diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp
index b4c559c81cc5..e87399f97baa 100644
--- a/source/Commands/CommandObjectExpression.cpp
+++ b/source/Commands/CommandObjectExpression.cpp
@@ -15,7 +15,6 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
@@ -24,6 +23,7 @@
#include "lldb/Expression/ClangFunction.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Host/Host.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -119,7 +119,7 @@ CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &int
{
bool success;
uint32_t result;
- result = Args::StringToUInt32(option_arg, 0, 0, &success);
+ result = StringConvert::ToUInt32(option_arg, 0, 0, &success);
if (success)
timeout = result;
else
diff --git a/source/Commands/CommandObjectFrame.cpp b/source/Commands/CommandObjectFrame.cpp
index ce540a5c3100..4458a692a189 100644
--- a/source/Commands/CommandObjectFrame.cpp
+++ b/source/Commands/CommandObjectFrame.cpp
@@ -27,6 +27,7 @@
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "lldb/Host/Host.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -119,7 +120,7 @@ public:
switch (short_option)
{
case 'r':
- relative_frame_offset = Args::StringToSInt32 (option_arg, INT32_MIN, 0, &success);
+ relative_frame_offset = StringConvert::ToSInt32 (option_arg, INT32_MIN, 0, &success);
if (!success)
error.SetErrorStringWithFormat ("invalid frame offset argument '%s'", option_arg);
break;
@@ -246,7 +247,7 @@ protected:
{
const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
bool success = false;
- frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0, &success);
+ frame_idx = StringConvert::ToUInt32 (frame_idx_cstr, UINT32_MAX, 0, &success);
if (!success)
{
result.AppendErrorWithFormat ("invalid frame index argument '%s'", frame_idx_cstr);
diff --git a/source/Commands/CommandObjectGUI.cpp b/source/Commands/CommandObjectGUI.cpp
index 3d05335e92e4..359d6d2892d0 100644
--- a/source/Commands/CommandObjectGUI.cpp
+++ b/source/Commands/CommandObjectGUI.cpp
@@ -42,10 +42,22 @@ CommandObjectGUI::DoExecute (Args& args, CommandReturnObject &result)
if (args.GetArgumentCount() == 0)
{
Debugger &debugger = m_interpreter.GetDebugger();
- IOHandlerSP io_handler_sp (new IOHandlerCursesGUI (debugger));
- if (io_handler_sp)
- debugger.PushIOHandler(io_handler_sp);
- result.SetStatus (eReturnStatusSuccessFinishResult);
+
+ lldb::StreamFileSP input_sp = debugger.GetInputFile();
+ if (input_sp &&
+ input_sp->GetFile().GetIsRealTerminal() &&
+ input_sp->GetFile().GetIsInteractive())
+ {
+ IOHandlerSP io_handler_sp (new IOHandlerCursesGUI (debugger));
+ if (io_handler_sp)
+ debugger.PushIOHandler(io_handler_sp);
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ }
+ else
+ {
+ result.AppendError("the gui command requires an interactive terminal.");
+ result.SetStatus (eReturnStatusFailed);
+ }
}
else
{
diff --git a/source/Commands/CommandObjectHelp.cpp b/source/Commands/CommandObjectHelp.cpp
index f73d9d23b574..b02515e2d1e8 100644
--- a/source/Commands/CommandObjectHelp.cpp
+++ b/source/Commands/CommandObjectHelp.cpp
@@ -54,9 +54,10 @@ CommandObjectHelp::~CommandObjectHelp()
OptionDefinition
CommandObjectHelp::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "show-aliases", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Show aliases in the command list."},
+ { LLDB_OPT_SET_ALL, false, "hide-aliases", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Hide aliases in the command list."},
{ LLDB_OPT_SET_ALL, false, "hide-user-commands", 'u', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Hide user-defined commands from the list."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+ { LLDB_OPT_SET_ALL, false, "show-hidden-commands", 'h', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Include commands prefixed with an underscore."},
+ { 0, false, NULL, 0, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
bool
@@ -75,6 +76,8 @@ CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result)
cmd_types |= CommandInterpreter::eCommandTypesAliases;
if (m_options.m_show_user_defined)
cmd_types |= CommandInterpreter::eCommandTypesUserDef;
+ if (m_options.m_show_hidden)
+ cmd_types |= CommandInterpreter::eCommandTypesHidden;
result.SetStatus (eReturnStatusSuccessFinishNoResult);
m_interpreter.GetHelp (result, cmd_types); // General help
@@ -136,17 +139,19 @@ CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result)
else if (!sub_cmd_obj)
{
result.AppendErrorWithFormat("'%s' is not a known command.\n"
- "Try 'help' to see a current list of commands.\n",
- cmd_string.c_str());
+ "Try '%shelp' to see a current list of commands.\n",
+ cmd_string.c_str(),
+ m_interpreter.GetCommandPrefix());
result.SetStatus (eReturnStatusFailed);
return false;
}
else
{
result.GetOutputStream().Printf("'%s' is not a known command.\n"
- "Try 'help' to see a current list of commands.\n"
+ "Try '%shelp' to see a current list of commands.\n"
"The closest match is '%s'. Help on it follows.\n\n",
cmd_string.c_str(),
+ m_interpreter.GetCommandPrefix(),
sub_cmd_obj->GetCommandName());
}
}
@@ -183,8 +188,9 @@ CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result)
else
{
result.AppendErrorWithFormat
- ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n",
- command.GetArgumentAtIndex(0));
+ ("'%s' is not a known command.\nTry '%shelp' to see a current list of commands.\n",
+ command.GetArgumentAtIndex(0),
+ m_interpreter.GetCommandPrefix());
result.SetStatus (eReturnStatusFailed);
}
}
diff --git a/source/Commands/CommandObjectHelp.h b/source/Commands/CommandObjectHelp.h
index 6e8f9d4cbc7b..7db659c472c9 100644
--- a/source/Commands/CommandObjectHelp.h
+++ b/source/Commands/CommandObjectHelp.h
@@ -62,11 +62,14 @@ public:
switch (short_option)
{
case 'a':
- m_show_aliases = true;
+ m_show_aliases = false;
break;
case 'u':
m_show_user_defined = false;
break;
+ case 'h':
+ m_show_hidden = true;
+ break;
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
@@ -78,8 +81,9 @@ public:
void
OptionParsingStarting ()
{
- m_show_aliases = false;
+ m_show_aliases = true;
m_show_user_defined = true;
+ m_show_hidden = false;
}
const OptionDefinition*
@@ -95,7 +99,8 @@ public:
// Instance variables to hold the values for command options.
bool m_show_aliases;
- bool m_show_user_defined;
+ bool m_show_user_defined;
+ bool m_show_hidden;
};
virtual Options *
diff --git a/source/Commands/CommandObjectLog.cpp b/source/Commands/CommandObjectLog.cpp
index 7d32cc6d08a5..aa09f53c792b 100644
--- a/source/Commands/CommandObjectLog.cpp
+++ b/source/Commands/CommandObjectLog.cpp
@@ -29,6 +29,7 @@
#include "lldb/Core/Timer.h"
#include "lldb/Core/Debugger.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -444,7 +445,7 @@ protected:
if (strcasecmp(sub_command, "enable") == 0)
{
bool success;
- uint32_t depth = Args::StringToUInt32(args.GetArgumentAtIndex(1), 0, 0, &success);
+ uint32_t depth = StringConvert::ToUInt32(args.GetArgumentAtIndex(1), 0, 0, &success);
if (success)
{
Timer::SetDisplayDepth (depth);
diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp
index 6c06ec831830..dac6dd81651b 100644
--- a/source/Commands/CommandObjectMemory.cpp
+++ b/source/Commands/CommandObjectMemory.cpp
@@ -24,6 +24,7 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObjectMemory.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -566,7 +567,7 @@ protected:
--pointer_count;
}
- m_format_options.GetByteSizeValue() = clang_ast_type.GetByteSize();
+ m_format_options.GetByteSizeValue() = clang_ast_type.GetByteSize(nullptr);
if (m_format_options.GetByteSizeValue() == 0)
{
@@ -689,7 +690,7 @@ protected:
if (m_format_options.GetFormatValue().OptionWasSet() == false)
m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault);
- bytes_read = clang_ast_type.GetByteSize() * m_format_options.GetCountValue().GetCurrentValue();
+ bytes_read = clang_ast_type.GetByteSize(nullptr) * m_format_options.GetCountValue().GetCurrentValue();
}
else if (m_format_options.GetFormatValue().GetCurrentValue() != eFormatCString)
{
@@ -1113,7 +1114,7 @@ protected:
if (process->GetTarget().EvaluateExpression(m_memory_options.m_expr.GetStringValue(), frame, result_sp) && result_sp.get())
{
uint64_t value = result_sp->GetValueAsUnsigned(0);
- switch (result_sp->GetClangType().GetByteSize())
+ switch (result_sp->GetClangType().GetByteSize(nullptr))
{
case 1: {
uint8_t byte = (uint8_t)value;
@@ -1293,7 +1294,7 @@ public:
case 'o':
{
bool success;
- m_infile_offset = Args::StringToUInt64(option_arg, 0, 0, &success);
+ m_infile_offset = StringConvert::ToUInt64(option_arg, 0, 0, &success);
if (!success)
{
error.SetErrorStringWithFormat("invalid offset string '%s'", option_arg);
@@ -1446,7 +1447,7 @@ protected:
if (m_memory_options.m_infile)
{
size_t length = SIZE_MAX;
- if (item_byte_size > 0)
+ if (item_byte_size > 1)
length = item_byte_size;
lldb::DataBufferSP data_sp (m_memory_options.m_infile.ReadFileContents (m_memory_options.m_infile_offset, length));
if (data_sp)
@@ -1539,7 +1540,7 @@ protected:
case eFormatPointer:
// Decode hex bytes
- uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 16, &success);
+ uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 16, &success);
if (!success)
{
result.AppendErrorWithFormat ("'%s' is not a valid hex string value.\n", value_str);
@@ -1567,7 +1568,7 @@ protected:
break;
case eFormatBinary:
- uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 2, &success);
+ uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 2, &success);
if (!success)
{
result.AppendErrorWithFormat ("'%s' is not a valid binary string value.\n", value_str);
@@ -1607,7 +1608,7 @@ protected:
break;
case eFormatDecimal:
- sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success);
+ sval64 = StringConvert::ToSInt64(value_str, INT64_MAX, 0, &success);
if (!success)
{
result.AppendErrorWithFormat ("'%s' is not a valid signed decimal value.\n", value_str);
@@ -1624,7 +1625,7 @@ protected:
break;
case eFormatUnsigned:
- uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success);
+ uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 0, &success);
if (!success)
{
result.AppendErrorWithFormat ("'%s' is not a valid unsigned decimal string value.\n", value_str);
@@ -1641,7 +1642,7 @@ protected:
break;
case eFormatOctal:
- uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 8, &success);
+ uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 8, &success);
if (!success)
{
result.AppendErrorWithFormat ("'%s' is not a valid octal string value.\n", value_str);
diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp
index d176d52cb487..959c5cd1d0d7 100644
--- a/source/Commands/CommandObjectPlatform.cpp
+++ b/source/Commands/CommandObjectPlatform.cpp
@@ -19,6 +19,7 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandOptionValidators.h"
@@ -104,7 +105,7 @@ public:
case 'v':
{
bool ok;
- uint32_t perms = Args::StringToUInt32(option_arg, 777, 8, &ok);
+ uint32_t perms = StringConvert::ToUInt32(option_arg, 777, 8, &ok);
if (!ok)
error.SetErrorStringWithFormat("invalid value for permissions: %s", option_arg);
else
@@ -248,6 +249,8 @@ protected:
PlatformSP platform_sp (m_platform_options.CreatePlatformWithOptions (m_interpreter, ArchSpec(), select, error, platform_arch));
if (platform_sp)
{
+ m_interpreter.GetDebugger().GetPlatformList().SetSelectedPlatform(platform_sp);
+
platform_sp->GetStatus (result.GetOutputStream());
result.SetStatus (eReturnStatusSuccessFinishResult);
}
@@ -613,7 +616,7 @@ public:
std::string cmd_line;
args.GetCommandString(cmd_line);
uint32_t mode;
- const OptionPermissions* options_permissions = (OptionPermissions*)m_options.GetGroupWithOption('r');
+ const OptionPermissions* options_permissions = (const OptionPermissions*)m_options.GetGroupWithOption('r');
if (options_permissions)
mode = options_permissions->m_permissions;
else
@@ -682,7 +685,7 @@ public:
std::string cmd_line;
args.GetCommandString(cmd_line);
mode_t perms;
- const OptionPermissions* options_permissions = (OptionPermissions*)m_options.GetGroupWithOption('r');
+ const OptionPermissions* options_permissions = (const OptionPermissions*)m_options.GetGroupWithOption('r');
if (options_permissions)
perms = options_permissions->m_permissions;
else
@@ -751,7 +754,7 @@ public:
{
std::string cmd_line;
args.GetCommandString(cmd_line);
- const lldb::user_id_t fd = Args::StringToUInt64(cmd_line.c_str(), UINT64_MAX);
+ const lldb::user_id_t fd = StringConvert::ToUInt64(cmd_line.c_str(), UINT64_MAX);
Error error;
bool success = platform_sp->CloseFile(fd, error);
if (success)
@@ -803,7 +806,7 @@ public:
{
std::string cmd_line;
args.GetCommandString(cmd_line);
- const lldb::user_id_t fd = Args::StringToUInt64(cmd_line.c_str(), UINT64_MAX);
+ const lldb::user_id_t fd = StringConvert::ToUInt64(cmd_line.c_str(), UINT64_MAX);
std::string buffer(m_options.m_count,0);
Error error;
uint32_t retcode = platform_sp->ReadFile(fd, m_options.m_offset, &buffer[0], m_options.m_count, error);
@@ -849,12 +852,12 @@ protected:
switch (short_option)
{
case 'o':
- m_offset = Args::StringToUInt32(option_arg, 0, 0, &success);
+ m_offset = StringConvert::ToUInt32(option_arg, 0, 0, &success);
if (!success)
error.SetErrorStringWithFormat("invalid offset: '%s'", option_arg);
break;
case 'c':
- m_count = Args::StringToUInt32(option_arg, 0, 0, &success);
+ m_count = StringConvert::ToUInt32(option_arg, 0, 0, &success);
if (!success)
error.SetErrorStringWithFormat("invalid offset: '%s'", option_arg);
break;
@@ -930,7 +933,7 @@ public:
std::string cmd_line;
args.GetCommandString(cmd_line);
Error error;
- const lldb::user_id_t fd = Args::StringToUInt64(cmd_line.c_str(), UINT64_MAX);
+ const lldb::user_id_t fd = StringConvert::ToUInt64(cmd_line.c_str(), UINT64_MAX);
uint32_t retcode = platform_sp->WriteFile (fd,
m_options.m_offset,
&m_options.m_data[0],
@@ -977,7 +980,7 @@ protected:
switch (short_option)
{
case 'o':
- m_offset = Args::StringToUInt32(option_arg, 0, 0, &success);
+ m_offset = StringConvert::ToUInt32(option_arg, 0, 0, &success);
if (!success)
error.SetErrorStringWithFormat("invalid offset: '%s'", option_arg);
break;
@@ -1537,37 +1540,37 @@ protected:
switch (short_option)
{
case 'p':
- match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
+ match_info.GetProcessInfo().SetProcessID (StringConvert::ToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
if (!success)
error.SetErrorStringWithFormat("invalid process ID string: '%s'", option_arg);
break;
case 'P':
- match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
+ match_info.GetProcessInfo().SetParentProcessID (StringConvert::ToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
if (!success)
error.SetErrorStringWithFormat("invalid parent process ID string: '%s'", option_arg);
break;
case 'u':
- match_info.GetProcessInfo().SetUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
+ match_info.GetProcessInfo().SetUserID (StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0, &success));
if (!success)
error.SetErrorStringWithFormat("invalid user ID string: '%s'", option_arg);
break;
case 'U':
- match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
+ match_info.GetProcessInfo().SetEffectiveUserID (StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0, &success));
if (!success)
error.SetErrorStringWithFormat("invalid effective user ID string: '%s'", option_arg);
break;
case 'g':
- match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
+ match_info.GetProcessInfo().SetGroupID (StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0, &success));
if (!success)
error.SetErrorStringWithFormat("invalid group ID string: '%s'", option_arg);
break;
case 'G':
- match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
+ match_info.GetProcessInfo().SetEffectiveGroupID (StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0, &success));
if (!success)
error.SetErrorStringWithFormat("invalid effective group ID string: '%s'", option_arg);
break;
@@ -1730,7 +1733,7 @@ protected:
for (size_t i=0; i<argc; ++ i)
{
const char *arg = args.GetArgumentAtIndex(i);
- lldb::pid_t pid = Args::StringToUInt32 (arg, LLDB_INVALID_PROCESS_ID, 0, &success);
+ lldb::pid_t pid = StringConvert::ToUInt32 (arg, LLDB_INVALID_PROCESS_ID, 0, &success);
if (success)
{
ProcessInstanceInfo proc_info;
@@ -1805,7 +1808,7 @@ public:
{
case 'p':
{
- lldb::pid_t pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
+ lldb::pid_t pid = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
if (!success || pid == LLDB_INVALID_PROCESS_ID)
{
error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
@@ -2055,7 +2058,7 @@ public:
case 't':
{
bool success;
- timeout = Args::StringToUInt32(option_value, 10, 10, &success);
+ timeout = StringConvert::ToUInt32(option_value, 10, 10, &success);
if (!success)
error.SetErrorStringWithFormat("could not convert \"%s\" to a numeric value.", option_value);
break;
@@ -2278,19 +2281,16 @@ CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) :
LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter)));
LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter)));
LoadSubCommand ("settings", CommandObjectSP (new CommandObjectPlatformSettings (interpreter)));
-#ifdef LLDB_CONFIGURATION_DEBUG
LoadSubCommand ("mkdir", CommandObjectSP (new CommandObjectPlatformMkDir (interpreter)));
LoadSubCommand ("file", CommandObjectSP (new CommandObjectPlatformFile (interpreter)));
LoadSubCommand ("get-file", CommandObjectSP (new CommandObjectPlatformGetFile (interpreter)));
LoadSubCommand ("get-size", CommandObjectSP (new CommandObjectPlatformGetSize (interpreter)));
LoadSubCommand ("put-file", CommandObjectSP (new CommandObjectPlatformPutFile (interpreter)));
-#endif
LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter)));
LoadSubCommand ("shell", CommandObjectSP (new CommandObjectPlatformShell (interpreter)));
LoadSubCommand ("target-install", CommandObjectSP (new CommandObjectPlatformInstall (interpreter)));
}
-
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp
index ec7b478fbecc..d47311e5cb5f 100644
--- a/source/Commands/CommandObjectProcess.cpp
+++ b/source/Commands/CommandObjectProcess.cpp
@@ -22,6 +22,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/Host.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -353,7 +354,7 @@ public:
case 'p':
{
- lldb::pid_t pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
+ lldb::pid_t pid = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
if (!success || pid == LLDB_INVALID_PROCESS_ID)
{
error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
@@ -488,6 +489,8 @@ protected:
DoExecute (Args& command,
CommandReturnObject &result)
{
+ PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
// N.B. The attach should be synchronous. It doesn't help much to get the prompt back between initiating the attach
// and the target actually stopping. So even if the interpreter is set to be asynchronous, we wait for the stop
@@ -526,122 +529,130 @@ protected:
ModuleSP old_exec_module_sp = target->GetExecutableModule();
ArchSpec old_arch_spec = target->GetArchitecture();
+ ProcessSP process_sp;
+ Error error;
if (command.GetArgumentCount())
{
result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
result.SetStatus (eReturnStatusFailed);
+ return false;
}
- else
+
+ m_interpreter.UpdateExecutionContext(nullptr);
+ ListenerSP listener_sp (new Listener("lldb.CommandObjectProcessAttach.DoExecute.attach.hijack"));
+ m_options.attach_info.SetHijackListener(listener_sp);
+
+ // If no process info was specified, then use the target executable
+ // name as the process to attach to by default
+ if (!m_options.attach_info.ProcessInfoSpecified ())
{
- if (state != eStateConnected)
+ if (old_exec_module_sp)
+ m_options.attach_info.GetExecutableFile().GetFilename() = old_exec_module_sp->GetPlatformFileSpec().GetFilename();
+
+ if (!m_options.attach_info.ProcessInfoSpecified ())
{
- const char *plugin_name = m_options.attach_info.GetProcessPluginName();
- process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, NULL).get();
+ error.SetErrorString ("no process specified, create a target with a file, or specify the --pid or --name command option");
}
+ }
- if (process)
+ if (error.Success())
+ {
+ if (state != eStateConnected && platform_sp != nullptr && platform_sp->CanDebugProcess())
+ {
+ target->SetPlatform(platform_sp);
+ process = platform_sp->Attach(m_options.attach_info, m_interpreter.GetDebugger(), target, error).get();
+ }
+ else
{
- Error error;
- // If no process info was specified, then use the target executable
- // name as the process to attach to by default
- if (!m_options.attach_info.ProcessInfoSpecified ())
+ if (state != eStateConnected)
{
- if (old_exec_module_sp)
- m_options.attach_info.GetExecutableFile().GetFilename() = old_exec_module_sp->GetPlatformFileSpec().GetFilename();
-
- if (!m_options.attach_info.ProcessInfoSpecified ())
- {
- error.SetErrorString ("no process specified, create a target with a file, or specify the --pid or --name command option");
- }
+ const char *plugin_name = m_options.attach_info.GetProcessPluginName();
+ process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name, nullptr).get();
+ if (process == nullptr)
+ error.SetErrorStringWithFormat("failed to create process using plugin %s", plugin_name);
}
-
- if (error.Success())
+ if (process)
{
- // Update the execution context so the current target and process are now selected
- // in case we interrupt
- m_interpreter.UpdateExecutionContext(NULL);
- ListenerSP listener_sp (new Listener("lldb.CommandObjectProcessAttach.DoExecute.attach.hijack"));
- m_options.attach_info.SetHijackListener(listener_sp);
process->HijackProcessEvents(listener_sp.get());
- error = process->Attach (m_options.attach_info);
-
- if (error.Success())
- {
- result.SetStatus (eReturnStatusSuccessContinuingNoResult);
- StreamString stream;
- StateType state = process->WaitForProcessToStop (NULL, NULL, false, listener_sp.get(), &stream);
-
- process->RestoreProcessEvents();
-
- result.SetDidChangeProcessState (true);
-
- if (stream.GetData())
- result.AppendMessage(stream.GetData());
-
- if (state == eStateStopped)
- {
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- const char *exit_desc = process->GetExitDescription();
- if (exit_desc)
- result.AppendErrorWithFormat ("attach failed: %s", exit_desc);
- else
- result.AppendError ("attach failed: process did not stop (no such process or permission problem?)");
- process->Destroy();
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
+ error = process->Attach(m_options.attach_info);
}
}
}
-
- if (result.Succeeded())
+
+ if (error.Success() && process != nullptr)
{
- // Okay, we're done. Last step is to warn if the executable module has changed:
- char new_path[PATH_MAX];
- ModuleSP new_exec_module_sp (target->GetExecutableModule());
- if (!old_exec_module_sp)
+ result.SetStatus (eReturnStatusSuccessContinuingNoResult);
+ StreamString stream;
+ StateType state = process->WaitForProcessToStop (nullptr, nullptr, false, listener_sp.get(), &stream);
+
+ process->RestoreProcessEvents();
+ result.SetDidChangeProcessState (true);
+
+ if (stream.GetData())
+ result.AppendMessage(stream.GetData());
+
+ if (state == eStateStopped)
{
- // We might not have a module if we attached to a raw pid...
- if (new_exec_module_sp)
- {
- new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
- result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
- }
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
- else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
- {
- char old_path[PATH_MAX];
-
- old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
- new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
-
- result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
- old_path, new_path);
- }
-
- if (!old_arch_spec.IsValid())
+ else
{
- result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
+ const char *exit_desc = process->GetExitDescription();
+ if (exit_desc)
+ result.AppendErrorWithFormat ("attach failed: %s", exit_desc);
+ else
+ result.AppendError ("attach failed: process did not stop (no such process or permission problem?)");
+ process->Destroy();
+ result.SetStatus (eReturnStatusFailed);
}
- else if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
+ result.SetStatus (eReturnStatusFailed);
+ }
+
+ if (!result.Succeeded())
+ return false;
+
+ // Okay, we're done. Last step is to warn if the executable module has changed:
+ char new_path[PATH_MAX];
+ ModuleSP new_exec_module_sp (target->GetExecutableModule());
+ if (!old_exec_module_sp)
+ {
+ // We might not have a module if we attached to a raw pid...
+ if (new_exec_module_sp)
{
- result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
- old_arch_spec.GetTriple().getTriple().c_str(),
- target->GetArchitecture().GetTriple().getTriple().c_str());
+ new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
+ result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
}
+ }
+ else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
+ {
+ char old_path[PATH_MAX];
- // This supports the use-case scenario of immediately continuing the process once attached.
- if (m_options.attach_info.GetContinueOnceAttached())
- m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
+ old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
+ new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
+
+ result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
+ old_path, new_path);
+ }
+
+ if (!old_arch_spec.IsValid())
+ {
+ result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
}
+ else if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
+ {
+ result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
+ old_arch_spec.GetTriple().getTriple().c_str(),
+ target->GetArchitecture().GetTriple().getTriple().c_str());
+ }
+
+ // This supports the use-case scenario of immediately continuing the process once attached.
+ if (m_options.attach_info.GetContinueOnceAttached())
+ m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
+
return result.Succeeded();
}
@@ -714,7 +725,7 @@ protected:
switch (short_option)
{
case 'i':
- m_ignore = Args::StringToUInt32 (option_arg, 0, 0, &success);
+ m_ignore = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
if (!success)
error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg);
break;
@@ -1297,7 +1308,7 @@ protected:
for (uint32_t i=0; i<argc; ++i)
{
const char *image_token_cstr = command.GetArgumentAtIndex(i);
- uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
+ uint32_t image_token = StringConvert::ToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
if (image_token == LLDB_INVALID_IMAGE_TOKEN)
{
result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
@@ -1371,7 +1382,7 @@ protected:
const char *signal_name = command.GetArgumentAtIndex(0);
if (::isxdigit (signal_name[0]))
- signo = Args::StringToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
+ signo = StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
else
signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name);
@@ -1754,7 +1765,7 @@ public:
else
{
// If the value isn't 'true' or 'false', it had better be 0 or 1.
- real_value = Args::StringToUInt32 (option.c_str(), 3);
+ real_value = StringConvert::ToUInt32 (option.c_str(), 3);
if (real_value != 0 && real_value != 1)
okay = false;
}
diff --git a/source/Commands/CommandObjectSource.cpp b/source/Commands/CommandObjectSource.cpp
index 8fb03e69ac42..a88a9b1f0cac 100644
--- a/source/Commands/CommandObjectSource.cpp
+++ b/source/Commands/CommandObjectSource.cpp
@@ -15,7 +15,6 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FileLineResolver.h"
#include "lldb/Core/Module.h"
@@ -24,6 +23,7 @@
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
@@ -63,7 +63,7 @@ class CommandObjectSourceInfo : public CommandObjectParsed
switch (short_option)
{
case 'l':
- start_line = Args::StringToUInt32 (option_arg, 0);
+ start_line = StringConvert::ToUInt32 (option_arg, 0);
if (start_line == 0)
error.SetErrorStringWithFormat("invalid line number: '%s'", option_arg);
break;
@@ -171,13 +171,13 @@ class CommandObjectSourceList : public CommandObjectParsed
switch (short_option)
{
case 'l':
- start_line = Args::StringToUInt32 (option_arg, 0);
+ start_line = StringConvert::ToUInt32 (option_arg, 0);
if (start_line == 0)
error.SetErrorStringWithFormat("invalid line number: '%s'", option_arg);
break;
case 'c':
- num_lines = Args::StringToUInt32 (option_arg, 0);
+ num_lines = StringConvert::ToUInt32 (option_arg, 0);
if (num_lines == 0)
error.SetErrorStringWithFormat("invalid line count: '%s'", option_arg);
break;
diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp
index 0d9ffda1e96b..9188283966f1 100644
--- a/source/Commands/CommandObjectTarget.cpp
+++ b/source/Commands/CommandObjectTarget.cpp
@@ -27,6 +27,7 @@
#include "lldb/Core/Timer.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -159,7 +160,6 @@ public:
NULL),
m_option_group (interpreter),
m_arch_option (),
- m_platform_options(true), // Do include the "--platform" option in the platform settings by passing true
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 symbols file for when debug symbols are not in the executable."),
@@ -180,7 +180,6 @@ 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, LLDB_OPT_SET_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);
@@ -282,70 +281,83 @@ protected:
bool must_set_platform_path = false;
Debugger &debugger = m_interpreter.GetDebugger();
- PlatformSP platform_sp(debugger.GetPlatformList().GetSelectedPlatform ());
- if (remote_file)
+ TargetSP target_sp;
+ const char *arch_cstr = m_arch_option.GetArchitectureName();
+ const bool get_dependent_files = m_add_dependents.GetOptionValue().GetCurrentValue();
+ Error error (debugger.GetTargetList().CreateTarget (debugger,
+ file_path,
+ arch_cstr,
+ get_dependent_files,
+ NULL,
+ target_sp));
+
+ if (target_sp)
{
- // I have a remote file.. two possible cases
- if (file_spec && file_spec.Exists())
+ // 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 the remote file does not exist, push it there
- if (!platform_sp->GetFileExists (remote_file))
+ if (platform_sp)
{
- Error err = platform_sp->PutFile(file_spec, remote_file);
- if (err.Fail())
+ // I have a remote file.. two possible cases
+ if (file_spec && file_spec.Exists())
{
- result.AppendError(err.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
+ // if the remote file does not exist, push it there
+ if (!platform_sp->GetFileExists (remote_file))
+ {
+ Error 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");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- if (file_path)
- {
- // copy the remote file to the local file
- Error err = platform_sp->GetFile(remote_file, file_spec);
- if (err.Fail())
+ else
{
- result.AppendError(err.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
+ // 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");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ if (file_path)
+ {
+ // copy the remote file to the local file
+ Error 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
{
- // make up a local file
- result.AppendError("remote --> local transfer without local path is not implemented yet");
+ result.AppendError("no platform found for target");
result.SetStatus (eReturnStatusFailed);
return false;
}
}
- }
- TargetSP target_sp;
- const char *arch_cstr = m_arch_option.GetArchitectureName();
- const bool get_dependent_files = m_add_dependents.GetOptionValue().GetCurrentValue();
- Error error (debugger.GetTargetList().CreateTarget (debugger,
-// remote_file ? remote_file : file_spec,
- file_path,
- arch_cstr,
- get_dependent_files,
- &m_platform_options,
- target_sp));
-
- if (target_sp)
- {
if (symfile || remote_file)
{
ModuleSP module_sp (target_sp->GetExecutableModule());
@@ -426,7 +438,7 @@ protected:
}
else
{
- result.AppendErrorWithFormat("'%s' takes exactly one executable path argument, or use the --core-file option.\n", m_cmd_name.c_str());
+ result.AppendErrorWithFormat("'%s' takes exactly one executable path argument, or use the --core option.\n", m_cmd_name.c_str());
result.SetStatus (eReturnStatusFailed);
}
return result.Succeeded();
@@ -435,7 +447,6 @@ protected:
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;
@@ -522,7 +533,7 @@ protected:
{
bool success = false;
const char *target_idx_arg = args.GetArgumentAtIndex(0);
- uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
+ uint32_t target_idx = StringConvert::ToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
if (success)
{
TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
@@ -629,7 +640,7 @@ protected:
for (uint32_t arg_idx = 0; success && arg_idx < argc; ++arg_idx)
{
const char *target_idx_arg = args.GetArgumentAtIndex(arg_idx);
- uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
+ uint32_t target_idx = StringConvert::ToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
if (success)
{
if (target_idx < num_targets)
@@ -1260,7 +1271,7 @@ protected:
{
bool success = false;
- uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
+ uint32_t insert_idx = StringConvert::ToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
if (!success)
{
@@ -2963,7 +2974,7 @@ protected:
{
ConstString const_sect_name(sect_name);
bool success = false;
- addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
+ addr_t load_addr = StringConvert::ToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
if (success)
{
SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
@@ -3890,7 +3901,7 @@ public:
break;
case 'o':
- m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
+ m_offset = StringConvert::ToUInt64(option_arg, LLDB_INVALID_ADDRESS);
if (m_offset == LLDB_INVALID_ADDRESS)
error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg);
break;
@@ -3910,7 +3921,7 @@ public:
break;
case 'l':
- m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
+ m_line_number = StringConvert::ToUInt32(option_arg, UINT32_MAX);
if (m_line_number == UINT32_MAX)
error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg);
else if (m_line_number == 0)
@@ -4078,7 +4089,7 @@ public:
if (LookupAddressInModule (m_interpreter,
result.GetOutputStream(),
module,
- eSymbolContextEverything,
+ eSymbolContextEverything | (m_options.m_verbose ? eSymbolContextVariable : 0),
m_options.m_addr,
m_options.m_offset,
m_options.m_verbose))
@@ -4873,7 +4884,7 @@ public:
break;
case 'e':
- m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
+ m_line_end = StringConvert::ToUInt32 (option_arg, UINT_MAX, 0, &success);
if (!success)
{
error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg);
@@ -4883,7 +4894,7 @@ public:
break;
case 'l':
- m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
+ m_line_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
if (!success)
{
error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg);
@@ -4912,7 +4923,7 @@ public:
break;
case 't' :
{
- m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
+ m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
if (m_thread_id == LLDB_INVALID_THREAD_ID)
error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
m_thread_specified = true;
@@ -4928,7 +4939,7 @@ public:
break;
case 'x':
{
- m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
+ m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
if (m_thread_id == UINT32_MAX)
error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
m_thread_specified = true;
@@ -5233,7 +5244,7 @@ protected:
bool success;
for (size_t i = 0; i < num_args; i++)
{
- lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
+ lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
if (!success)
{
result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
@@ -5302,7 +5313,7 @@ protected:
{
for (size_t i = 0; i < num_args; i++)
{
- lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
+ lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
if (!success)
{
result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp
index bace4e58b4ad..199d16b85205 100644
--- a/source/Commands/CommandObjectThread.cpp
+++ b/source/Commands/CommandObjectThread.cpp
@@ -19,6 +19,7 @@
#include "lldb/Core/State.h"
#include "lldb/Core/SourceManager.h"
#include "lldb/Host/Host.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/Options.h"
@@ -95,7 +96,7 @@ public:
{
bool success;
- uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
+ uint32_t thread_idx = StringConvert::ToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
if (!success)
{
result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
@@ -178,7 +179,7 @@ public:
case 'c':
{
bool success;
- int32_t input_count = Args::StringToSInt32 (option_arg, -1, 0, &success);
+ int32_t input_count = StringConvert::ToSInt32 (option_arg, -1, 0, &success);
if (!success)
error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
if (input_count < -1)
@@ -190,7 +191,7 @@ public:
case 's':
{
bool success;
- m_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
+ m_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
if (!success)
error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
}
@@ -384,7 +385,7 @@ public:
case 'c':
{
- m_step_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
+ m_step_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
if (m_step_count == UINT32_MAX)
error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
break;
@@ -522,7 +523,7 @@ protected:
else
{
const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
- uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
+ uint32_t step_thread_idx = StringConvert::ToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
if (step_thread_idx == LLDB_INVALID_INDEX32)
{
result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
@@ -812,7 +813,7 @@ public:
{
bool success;
const int base = 0;
- uint32_t thread_idx = Args::StringToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
+ uint32_t thread_idx = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
if (success)
{
Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
@@ -984,9 +985,17 @@ public:
switch (short_option)
{
+ case 'a':
+ {
+ ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
+ lldb::addr_t tmp_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
+ if (error.Success())
+ m_until_addrs.push_back(tmp_addr);
+ }
+ break;
case 't':
{
- m_thread_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_INDEX32);
+ m_thread_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_INDEX32);
if (m_thread_idx == LLDB_INVALID_INDEX32)
{
error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
@@ -995,7 +1004,7 @@ public:
break;
case 'f':
{
- m_frame_idx = Args::StringToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
+ m_frame_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
if (m_frame_idx == LLDB_INVALID_FRAME_ID)
{
error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
@@ -1030,6 +1039,7 @@ public:
m_thread_idx = LLDB_INVALID_THREAD_ID;
m_frame_idx = 0;
m_stop_others = false;
+ m_until_addrs.clear();
}
const OptionDefinition*
@@ -1040,6 +1050,7 @@ public:
uint32_t m_step_thread_idx;
bool m_stop_others;
+ std::vector<lldb::addr_t> m_until_addrs;
// Options table: Required for subclasses of Options.
@@ -1051,7 +1062,7 @@ public:
CommandObjectThreadUntil (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
"thread until",
- "Run the current or specified thread until it reaches a given line number or leaves the current function.",
+ "Run the current or specified thread until it reaches a given line number or address or leaves the current function.",
NULL,
eFlagRequiresThread |
eFlagTryTargetAPILock |
@@ -1110,23 +1121,33 @@ protected:
else
{
Thread *thread = NULL;
- uint32_t line_number;
+ std::vector<uint32_t> line_numbers;
- if (command.GetArgumentCount() != 1)
+ if (command.GetArgumentCount() >= 1)
{
- result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax());
- result.SetStatus (eReturnStatusFailed);
- return false;
+ size_t num_args = command.GetArgumentCount();
+ for (size_t i = 0; i < num_args; i++)
+ {
+ uint32_t line_number;
+ line_number = StringConvert::ToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
+ if (line_number == UINT32_MAX)
+ {
+ result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ else
+ line_numbers.push_back(line_number);
+ }
}
-
- line_number = Args::StringToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
- if (line_number == UINT32_MAX)
+ else if (m_options.m_until_addrs.empty())
{
- result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
+ result.AppendErrorWithFormat ("No line number or address provided:\n%s", GetSyntax());
result.SetStatus (eReturnStatusFailed);
return false;
}
+
if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
{
thread = process->GetThreadList().GetSelectedThread().get();
@@ -1188,27 +1209,40 @@ protected:
Address fun_end_addr(fun_start_addr.GetSection(),
fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
- line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
bool all_in_function = true;
-
- while (index_ptr <= end_ptr)
+
+ line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
+
+ for (uint32_t line_number : line_numbers)
{
- LineEntry line_entry;
- const bool exact = false;
- index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
- if (index_ptr == UINT32_MAX)
- break;
-
- addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
- if (address != LLDB_INVALID_ADDRESS)
+ uint32_t start_idx_ptr = index_ptr;
+ while (start_idx_ptr <= end_ptr)
{
- if (fun_addr_range.ContainsLoadAddress (address, target))
- address_list.push_back (address);
- else
- all_in_function = false;
+ LineEntry line_entry;
+ const bool exact = false;
+ start_idx_ptr = sc.comp_unit->FindLineEntry(start_idx_ptr, line_number, sc.comp_unit, exact, &line_entry);
+ if (start_idx_ptr == UINT32_MAX)
+ break;
+
+ addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
+ if (address != LLDB_INVALID_ADDRESS)
+ {
+ if (fun_addr_range.ContainsLoadAddress (address, target))
+ address_list.push_back (address);
+ else
+ all_in_function = false;
+ }
+ start_idx_ptr++;
}
- index_ptr++;
+ }
+
+ for (lldb::addr_t address : m_options.m_until_addrs)
+ {
+ if (fun_addr_range.ContainsLoadAddress (address, target))
+ address_list.push_back (address);
+ else
+ all_in_function = false;
}
if (address_list.size() == 0)
@@ -1290,7 +1324,8 @@ CommandObjectThreadUntil::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
-{ LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, NULL, g_duo_running_mode, 0, eArgTypeRunMode,"Determine how to run other threads while stepping this one"},
+{ LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, NULL, g_duo_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping this one"},
+{ LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Run until we reach the specified address, or leave the function - can be specified multiple times."},
{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};
@@ -1351,7 +1386,7 @@ protected:
return false;
}
- uint32_t index_id = Args::StringToUInt32(command.GetArgumentAtIndex(0), 0, 0);
+ uint32_t index_id = StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0);
Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
if (new_thread == NULL)
@@ -1796,12 +1831,12 @@ public:
return Error("only one source file expected.");
break;
case 'l':
- m_line_num = Args::StringToUInt32 (option_arg, 0, 0, &success);
+ m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
if (!success || m_line_num == 0)
return Error("invalid line number: '%s'.", option_arg);
break;
case 'b':
- m_line_offset = Args::StringToSInt32 (option_arg, 0, 0, &success);
+ m_line_offset = StringConvert::ToSInt32 (option_arg, 0, 0, &success);
if (!success)
return Error("invalid line offset: '%s'.", option_arg);
break;
@@ -2120,7 +2155,7 @@ public:
}
bool success;
- uint32_t thread_plan_idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
+ uint32_t thread_plan_idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
if (!success)
{
result.AppendErrorWithFormat("Invalid thread index: \"%s\" - should be unsigned int.",
diff --git a/source/Commands/CommandObjectWatchpoint.cpp b/source/Commands/CommandObjectWatchpoint.cpp
index ca5fe98ccb31..bef59ca30b3c 100644
--- a/source/Commands/CommandObjectWatchpoint.cpp
+++ b/source/Commands/CommandObjectWatchpoint.cpp
@@ -21,6 +21,7 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectVariable.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/CommandCompletions.h"
@@ -639,7 +640,7 @@ public:
{
case 'i':
{
- m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
+ m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
if (m_ignore_count == UINT32_MAX)
error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
}
diff --git a/source/Core/Address.cpp b/source/Core/Address.cpp
index a79becbf49c4..d449d0b21438 100644
--- a/source/Core/Address.cpp
+++ b/source/Core/Address.cpp
@@ -654,7 +654,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
if (module_sp)
{
SymbolContext sc;
- module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
+ module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything | eSymbolContextVariable, sc);
if (sc.function || sc.symbol)
{
bool show_stop_context = true;
@@ -712,7 +712,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
if (module_sp)
{
SymbolContext sc;
- module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
+ module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything | eSymbolContextVariable, sc);
if (sc.symbol)
{
// If we have just a symbol make sure it is in the same section
diff --git a/source/Core/ArchSpec.cpp b/source/Core/ArchSpec.cpp
index e7a5e489af19..015f76bffbb5 100644
--- a/source/Core/ArchSpec.cpp
+++ b/source/Core/ArchSpec.cpp
@@ -765,6 +765,19 @@ ArchSpec::SetTriple (const char *triple_cstr, Platform *platform)
return IsValid();
}
+void
+ArchSpec::MergeFrom(const ArchSpec &other)
+{
+ if (GetTriple().getVendor() == llvm::Triple::UnknownVendor && !TripleVendorWasSpecified())
+ GetTriple().setVendor(other.GetTriple().getVendor());
+ if (GetTriple().getOS() == llvm::Triple::UnknownOS && !TripleOSWasSpecified())
+ GetTriple().setOS(other.GetTriple().getOS());
+ if (GetTriple().getArch() == llvm::Triple::UnknownArch)
+ GetTriple().setArch(other.GetTriple().getArch());
+ if (GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment)
+ GetTriple().setEnvironment(other.GetTriple().getEnvironment());
+}
+
bool
ArchSpec::SetArchitecture (ArchitectureType arch_type, uint32_t cpu, uint32_t sub)
{
diff --git a/source/Core/Broadcaster.cpp b/source/Core/Broadcaster.cpp
index dc37516c29c2..1cbbde20e7f6 100644
--- a/source/Core/Broadcaster.cpp
+++ b/source/Core/Broadcaster.cpp
@@ -303,6 +303,16 @@ Broadcaster::HijackBroadcaster (Listener *listener, uint32_t event_mask)
return true;
}
+bool
+Broadcaster::IsHijackedForEvent (uint32_t event_mask)
+{
+ Mutex::Locker event_types_locker(m_listeners_mutex);
+
+ if (!m_hijacking_listeners.empty())
+ return (event_mask & m_hijacking_masks.back()) != 0;
+ return false;
+}
+
void
Broadcaster::RestoreBroadcaster ()
{
diff --git a/source/Core/ConnectionMachPort.cpp b/source/Core/ConnectionMachPort.cpp
index 05ada9872b5b..fe29814be420 100644
--- a/source/Core/ConnectionMachPort.cpp
+++ b/source/Core/ConnectionMachPort.cpp
@@ -107,6 +107,7 @@ ConnectionMachPort::Connect (const char *s, Error *error_ptr)
{
if (error_ptr)
error_ptr->Clear();
+ m_uri.assign(s);
}
else
{
@@ -209,6 +210,7 @@ ConnectionMachPort::Disconnect (Error *error_ptr)
error_ptr->SetError (kret, eErrorTypeMachKernel);
m_port = MACH_PORT_TYPE_NONE;
}
+ m_uri.clear();
return eConnectionStatusSuccess;
}
@@ -256,6 +258,12 @@ ConnectionMachPort::Write (const void *src, size_t src_len, ConnectionStatus &st
return 0;
}
+std::string
+ConnectionMachPort::GetURI()
+{
+ return m_uri;
+}
+
ConnectionStatus
ConnectionMachPort::BytesAvailable (uint32_t timeout_usec, Error *error_ptr)
{
diff --git a/source/Core/ConnectionSharedMemory.cpp b/source/Core/ConnectionSharedMemory.cpp
index 1cbee20cd94a..d3dfa3cd8d56 100644
--- a/source/Core/ConnectionSharedMemory.cpp
+++ b/source/Core/ConnectionSharedMemory.cpp
@@ -107,6 +107,13 @@ ConnectionSharedMemory::Write (const void *src, size_t src_len, ConnectionStatus
return 0;
}
+std::string
+ConnectionSharedMemory::GetURI()
+{
+ // TODO: fix when Connect is fixed?
+ return "";
+}
+
ConnectionStatus
ConnectionSharedMemory::BytesAvailable (uint32_t timeout_usec, Error *error_ptr)
{
diff --git a/source/Core/ConstString.cpp b/source/Core/ConstString.cpp
index 37d24e0dec00..85f8d3c65cd9 100644
--- a/source/Core/ConstString.cpp
+++ b/source/Core/ConstString.cpp
@@ -11,7 +11,7 @@
#include "lldb/Host/Mutex.h"
#include "llvm/ADT/StringMap.h"
-#include <mutex>
+#include <mutex> // std::once
using namespace lldb_private;
diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp
index c7342ade6cad..f25a3f41825f 100644
--- a/source/Core/Debugger.cpp
+++ b/source/Core/Debugger.cpp
@@ -18,6 +18,7 @@
#include "llvm/ADT/StringRef.h"
#include "lldb/lldb-private.h"
+#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegisterValue.h"
@@ -130,24 +131,23 @@ g_language_enumerators[] =
static PropertyDefinition
g_properties[] =
{
-{ "auto-confirm", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
-{ "disassembly-format", OptionValue::eTypeString , true, 0 , DEFAULT_DISASSEMBLY_FORMAT, NULL, "The default disassembly format string to use when disassembling instruction sequences." },
-{ "frame-format", OptionValue::eTypeString , true, 0 , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." },
-{ "notify-void", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
-{ "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
-{ "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
-{ "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
-{ "stop-disassembly-display", OptionValue::eTypeEnum , true, Debugger::eStopDisassemblyTypeNoSource, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." },
-{ "stop-line-count-after", OptionValue::eTypeSInt64 , true, 3 , NULL, NULL, "The number of sources lines to display that come after the current source line when displaying a stopped context." },
-{ "stop-line-count-before", OptionValue::eTypeSInt64 , true, 3 , NULL, NULL, "The number of sources lines to display that come before the current source line when displaying a stopped context." },
-{ "term-width", OptionValue::eTypeSInt64 , true, 80 , NULL, NULL, "The maximum number of columns to use for displaying text." },
-{ "thread-format", OptionValue::eTypeString , true, 0 , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
-{ "use-external-editor", OptionValue::eTypeBoolean, true, false, NULL, NULL, "Whether to use an external editor or not." },
-{ "use-color", OptionValue::eTypeBoolean, true, true , NULL, NULL, "Whether to use Ansi color codes or not." },
-{ "auto-one-line-summaries", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will automatically display small structs in one-liner format (default: true)." },
-{ "escape-non-printables", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." },
-
- { NULL, OptionValue::eTypeInvalid, true, 0 , NULL, NULL, NULL }
+{ "auto-confirm", OptionValue::eTypeBoolean , true, false, NULL, NULL, "If true all confirmation prompts will receive their default reply." },
+{ "disassembly-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_DISASSEMBLY_FORMAT, NULL, "The default disassembly format string to use when disassembling instruction sequences." },
+{ "frame-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_FRAME_FORMAT, NULL, "The default frame format string to use when displaying stack frame information for threads." },
+{ "notify-void", OptionValue::eTypeBoolean , true, false, NULL, NULL, "Notify the user explicitly if an expression returns void (default: false)." },
+{ "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." },
+{ "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
+{ "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." },
+{ "stop-disassembly-display", OptionValue::eTypeEnum , true, Debugger::eStopDisassemblyTypeNoSource, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." },
+{ "stop-line-count-after", OptionValue::eTypeSInt64 , true, 3 , NULL, NULL, "The number of sources lines to display that come after the current source line when displaying a stopped context." },
+{ "stop-line-count-before", OptionValue::eTypeSInt64 , true, 3 , NULL, NULL, "The number of sources lines to display that come before the current source line when displaying a stopped context." },
+{ "term-width", OptionValue::eTypeSInt64 , true, 80 , NULL, NULL, "The maximum number of columns to use for displaying text." },
+{ "thread-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_THREAD_FORMAT, NULL, "The default thread format string to use when displaying thread information." },
+{ "use-external-editor", OptionValue::eTypeBoolean , true, false, NULL, NULL, "Whether to use an external editor or not." },
+{ "use-color", OptionValue::eTypeBoolean , true, true , NULL, NULL, "Whether to use Ansi color codes or not." },
+{ "auto-one-line-summaries", OptionValue::eTypeBoolean , true, true, NULL, NULL, "If true, LLDB will automatically display small structs in one-liner format (default: true)." },
+{ "escape-non-printables", OptionValue::eTypeBoolean , true, true, NULL, NULL, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." },
+{ NULL, OptionValue::eTypeInvalid , true, 0 , NULL, NULL, NULL }
};
enum
@@ -242,18 +242,18 @@ Debugger::GetAutoConfirm () const
return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
}
-const char *
+const FormatEntity::Entry *
Debugger::GetDisassemblyFormat() const
{
const uint32_t idx = ePropertyDisassemblyFormat;
- return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
}
-const char *
+const FormatEntity::Entry *
Debugger::GetFrameFormat() const
{
const uint32_t idx = ePropertyFrameFormat;
- return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
}
bool
@@ -282,11 +282,11 @@ Debugger::SetPrompt(const char *p)
GetCommandInterpreter().UpdatePrompt(new_prompt);
}
-const char *
+const FormatEntity::Entry *
Debugger::GetThreadFormat() const
{
const uint32_t idx = ePropertyThreadFormat;
- return m_collection_sp->GetPropertyAtIndexAsString (NULL, idx, g_properties[idx].default_cstr_value);
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(NULL, idx);
}
lldb::ScriptLanguage
@@ -927,6 +927,18 @@ Debugger::GetTopIOHandlerControlSequence(char ch)
return m_input_reader_stack.GetTopIOHandlerControlSequence (ch);
}
+const char *
+Debugger::GetIOHandlerCommandPrefix()
+{
+ return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
+}
+
+const char *
+Debugger::GetIOHandlerHelpPrologue()
+{
+ return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
+}
+
void
Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
{
@@ -1214,1691 +1226,25 @@ TestPromptFormats (StackFrame *frame)
}
#endif
-static bool
-ScanFormatDescriptor (const char* var_name_begin,
- const char* var_name_end,
- const char** var_name_final,
- const char** percent_position,
- Format* custom_format,
- ValueObject::ValueObjectRepresentationStyle* val_obj_display)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
- *percent_position = ::strchr(var_name_begin,'%');
- if (!*percent_position || *percent_position > var_name_end)
- {
- if (log)
- log->Printf("[ScanFormatDescriptor] no format descriptor in string, skipping");
- *var_name_final = var_name_end;
- }
- else
- {
- *var_name_final = *percent_position;
- std::string format_name(*var_name_final+1, var_name_end-*var_name_final-1);
- if (log)
- log->Printf("[ScanFormatDescriptor] parsing %s as a format descriptor", format_name.c_str());
- if ( !FormatManager::GetFormatFromCString(format_name.c_str(),
- true,
- *custom_format) )
- {
- if (log)
- log->Printf("[ScanFormatDescriptor] %s is an unknown format", format_name.c_str());
-
- switch (format_name.front())
- {
- case '@': // if this is an @ sign, print ObjC description
- *val_obj_display = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
- break;
- case 'V': // if this is a V, print the value using the default format
- *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
- break;
- case 'L': // if this is an L, print the location of the value
- *val_obj_display = ValueObject::eValueObjectRepresentationStyleLocation;
- break;
- case 'S': // if this is an S, print the summary after all
- *val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
- break;
- case '#': // if this is a '#', print the number of children
- *val_obj_display = ValueObject::eValueObjectRepresentationStyleChildrenCount;
- break;
- case 'T': // if this is a 'T', print the type
- *val_obj_display = ValueObject::eValueObjectRepresentationStyleType;
- break;
- case 'N': // if this is a 'N', print the name
- *val_obj_display = ValueObject::eValueObjectRepresentationStyleName;
- break;
- case '>': // if this is a '>', print the name
- *val_obj_display = ValueObject::eValueObjectRepresentationStyleExpressionPath;
- break;
- default:
- if (log)
- log->Printf("ScanFormatDescriptor] %s is an error, leaving the previous value alone", format_name.c_str());
- break;
- }
- }
- // a good custom format tells us to print the value using it
- else
- {
- if (log)
- log->Printf("[ScanFormatDescriptor] will display value for this VO");
- *val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
- }
- }
- if (log)
- log->Printf("[ScanFormatDescriptor] final format description outcome: custom_format = %d, val_obj_display = %d",
- *custom_format,
- *val_obj_display);
- return true;
-}
-
-static bool
-ScanBracketedRange (const char* var_name_begin,
- const char* var_name_end,
- const char* var_name_final,
- const char** open_bracket_position,
- const char** separator_position,
- const char** close_bracket_position,
- const char** var_name_final_if_array_range,
- int64_t* index_lower,
- int64_t* index_higher)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
- *open_bracket_position = ::strchr(var_name_begin,'[');
- if (*open_bracket_position && *open_bracket_position < var_name_final)
- {
- *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield
- *close_bracket_position = ::strchr(*open_bracket_position,']');
- // as usual, we assume that [] will come before %
- //printf("trying to expand a []\n");
- *var_name_final_if_array_range = *open_bracket_position;
- if (*close_bracket_position - *open_bracket_position == 1)
- {
- if (log)
- log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
- *index_lower = 0;
- }
- else if (*separator_position == NULL || *separator_position > var_name_end)
- {
- char *end = NULL;
- *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
- *index_higher = *index_lower;
- if (log)
- log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower);
- }
- else if (*close_bracket_position && *close_bracket_position < var_name_end)
- {
- char *end = NULL;
- *index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
- *index_higher = ::strtoul (*separator_position+1, &end, 0);
- if (log)
- log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher);
- }
- else
- {
- if (log)
- log->Printf("[ScanBracketedRange] expression is erroneous, cannot extract indices out of it");
- return false;
- }
- if (*index_lower > *index_higher && *index_higher > 0)
- {
- if (log)
- log->Printf("[ScanBracketedRange] swapping indices");
- int64_t temp = *index_lower;
- *index_lower = *index_higher;
- *index_higher = temp;
- }
- }
- else if (log)
- log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
- return true;
-}
-
-template <typename T>
-static bool RunScriptFormatKeyword(Stream &s, ScriptInterpreter *script_interpreter, T t, const std::string& script_name)
-{
- if (script_interpreter)
- {
- Error script_error;
- std::string script_output;
-
- if (script_interpreter->RunScriptFormatKeyword(script_name.c_str(), t, script_output, script_error) && script_error.Success())
- {
- s.Printf("%s", script_output.c_str());
- return true;
- }
- else
- {
- s.Printf("<error: %s>",script_error.AsCString());
- }
- }
- return false;
-}
-
-static ValueObjectSP
-ExpandIndexedExpression (ValueObject* valobj,
- size_t index,
- StackFrame* frame,
- bool deref_pointer)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
- const char* ptr_deref_format = "[%d]";
- std::string ptr_deref_buffer(10,0);
- ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
- if (log)
- log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
- const char* first_unparsed;
- ValueObject::GetValueForExpressionPathOptions options;
- ValueObject::ExpressionPathEndResultType final_value_type;
- ValueObject::ExpressionPathScanEndReason reason_to_stop;
- ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
- ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
- &first_unparsed,
- &reason_to_stop,
- &final_value_type,
- options,
- &what_next);
- if (!item)
- {
- if (log)
- log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
- " final_value_type %d",
- first_unparsed, reason_to_stop, final_value_type);
- }
- else
- {
- if (log)
- log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
- " final_value_type %d",
- first_unparsed, reason_to_stop, final_value_type);
- }
- return item;
-}
-
-static inline bool
-IsToken(const char *var_name_begin, const char *var)
-{
- return (::strncmp (var_name_begin, var, strlen(var)) == 0);
-}
-
-static bool
-IsTokenWithFormat(const char *var_name_begin, const char *var, std::string &format, const char *default_format,
- const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr)
-{
- int var_len = strlen(var);
- if (::strncmp (var_name_begin, var, var_len) == 0)
- {
- var_name_begin += var_len;
- if (*var_name_begin == '}')
- {
- format = default_format;
- return true;
- }
- else if (*var_name_begin == '%')
- {
- // Allow format specifiers: x|X|u with optional width specifiers.
- // ${thread.id%x} ; hex
- // ${thread.id%X} ; uppercase hex
- // ${thread.id%u} ; unsigned decimal
- // ${thread.id%8.8X} ; width.precision + specifier
- // ${thread.id%tid} ; unsigned on FreeBSD/Linux, otherwise default_format (0x%4.4x for thread.id)
- int dot_count = 0;
- const char *specifier = NULL;
- int width_precision_length = 0;
- const char *width_precision = ++var_name_begin;
- while (isdigit(*var_name_begin) || *var_name_begin == '.')
- {
- dot_count += (*var_name_begin == '.');
- if (dot_count > 1)
- break;
- var_name_begin++;
- width_precision_length++;
- }
-
- if (IsToken (var_name_begin, "tid}"))
- {
- Target *target = Target::GetTargetFromContexts (exe_ctx_ptr, sc_ptr);
- if (target)
- {
- ArchSpec arch (target->GetArchitecture ());
- llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS;
- if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux))
- specifier = PRIu64;
- }
- if (!specifier)
- {
- format = default_format;
- return true;
- }
- }
- else if (IsToken (var_name_begin, "x}"))
- specifier = PRIx64;
- else if (IsToken (var_name_begin, "X}"))
- specifier = PRIX64;
- else if (IsToken (var_name_begin, "u}"))
- specifier = PRIu64;
-
- if (specifier)
- {
- format = "%";
- if (width_precision_length)
- format += std::string(width_precision, width_precision_length);
- format += specifier;
- return true;
- }
- }
- }
- return false;
-}
-
-// Find information for the "thread.info.*" specifiers in a format string
-static bool
-FormatThreadExtendedInfoRecurse
-(
- const char *var_name_begin,
- StructuredData::ObjectSP thread_info_dictionary,
- const SymbolContext *sc,
- const ExecutionContext *exe_ctx,
- Stream &s
-)
-{
- bool var_success = false;
- std::string token_format;
-
- llvm::StringRef var_name(var_name_begin);
- size_t percent_idx = var_name.find('%');
- size_t close_curly_idx = var_name.find('}');
- llvm::StringRef path = var_name;
- llvm::StringRef formatter = var_name;
-
- // 'path' will be the dot separated list of objects to transverse up until we hit
- // a close curly brace, a percent sign, or an end of string.
- if (percent_idx != llvm::StringRef::npos || close_curly_idx != llvm::StringRef::npos)
- {
- if (percent_idx != llvm::StringRef::npos && close_curly_idx != llvm::StringRef::npos)
- {
- if (percent_idx < close_curly_idx)
- {
- path = var_name.slice(0, percent_idx);
- formatter = var_name.substr (percent_idx);
- }
- else
- {
- path = var_name.slice(0, close_curly_idx);
- formatter = var_name.substr (close_curly_idx);
- }
- }
- else if (percent_idx != llvm::StringRef::npos)
- {
- path = var_name.slice(0, percent_idx);
- formatter = var_name.substr (percent_idx);
- }
- else if (close_curly_idx != llvm::StringRef::npos)
- {
- path = var_name.slice(0, close_curly_idx);
- formatter = var_name.substr (close_curly_idx);
- }
- }
-
- StructuredData::ObjectSP value = thread_info_dictionary->GetObjectForDotSeparatedPath (path);
-
- if (value.get())
- {
- if (value->GetType() == StructuredData::Type::eTypeInteger)
- {
- if (IsTokenWithFormat (formatter.str().c_str(), "", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
- {
- s.Printf(token_format.c_str(), value->GetAsInteger()->GetValue());
- var_success = true;
- }
- }
- else if (value->GetType() == StructuredData::Type::eTypeFloat)
- {
- s.Printf ("%f", value->GetAsFloat()->GetValue());
- var_success = true;
- }
- else if (value->GetType() == StructuredData::Type::eTypeString)
- {
- s.Printf("%s", value->GetAsString()->GetValue().c_str());
- var_success = true;
- }
- else if (value->GetType() == StructuredData::Type::eTypeArray)
- {
- if (value->GetAsArray()->GetSize() > 0)
- {
- s.Printf ("%zu", value->GetAsArray()->GetSize());
- var_success = true;
- }
- }
- else if (value->GetType() == StructuredData::Type::eTypeDictionary)
- {
- s.Printf ("%zu", value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
- var_success = true;
- }
- }
-
- return var_success;
-}
-
-
-static bool
-FormatPromptRecurse
-(
- const char *format,
- const SymbolContext *sc,
- const ExecutionContext *exe_ctx,
- const Address *addr,
- Stream &s,
- const char **end,
- ValueObject* valobj,
- bool function_changed,
- bool initial_function
-)
-{
- ValueObject* realvalobj = NULL; // makes it super-easy to parse pointers
- bool success = true;
- const char *p;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
-
- for (p = format; *p != '\0'; ++p)
- {
- if (realvalobj)
- {
- valobj = realvalobj;
- realvalobj = NULL;
- }
- size_t non_special_chars = ::strcspn (p, "${}\\");
- if (non_special_chars > 0)
- {
- if (success)
- s.Write (p, non_special_chars);
- p += non_special_chars;
- }
-
- if (*p == '\0')
- {
- break;
- }
- else if (*p == '{')
- {
- // Start a new scope that must have everything it needs if it is to
- // to make it into the final output stream "s". If you want to make
- // a format that only prints out the function or symbol name if there
- // is one in the symbol context you can use:
- // "{function =${function.name}}"
- // The first '{' starts a new scope that end with the matching '}' at
- // the end of the string. The contents "function =${function.name}"
- // will then be evaluated and only be output if there is a function
- // or symbol with a valid name.
- StreamString sub_strm;
-
- ++p; // Skip the '{'
-
- if (FormatPromptRecurse (p, sc, exe_ctx, addr, sub_strm, &p, valobj, function_changed, initial_function))
- {
- // The stream had all it needed
- s.Write(sub_strm.GetData(), sub_strm.GetSize());
- }
- if (*p != '}')
- {
- success = false;
- break;
- }
- }
- else if (*p == '}')
- {
- // End of a enclosing scope
- break;
- }
- else if (*p == '$')
- {
- // We have a prompt variable to print
- ++p;
- if (*p == '{')
- {
- ++p;
- const char *var_name_begin = p;
- const char *var_name_end = ::strchr (p, '}');
-
- if (var_name_end && var_name_begin < var_name_end)
- {
- // if we have already failed to parse, skip this variable
- if (success)
- {
- const char *cstr = NULL;
- std::string token_format;
- Address format_addr;
-
- // normally "addr" means print a raw address but
- // "file-addr-or-load-addr" means print a module + file addr if there's no load addr
- bool print_file_addr_or_load_addr = false;
- bool addr_offset_concrete_func_only = false;
- bool addr_offset_print_with_no_padding = false;
- bool calculate_format_addr_function_offset = false;
- // Set reg_kind and reg_num to invalid values
- RegisterKind reg_kind = kNumRegisterKinds;
- uint32_t reg_num = LLDB_INVALID_REGNUM;
- FileSpec format_file_spec;
- const RegisterInfo *reg_info = NULL;
- RegisterContext *reg_ctx = NULL;
- bool do_deref_pointer = false;
- ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
- ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
-
- // Each variable must set success to true below...
- bool var_success = false;
- switch (var_name_begin[0])
- {
- case '*':
- case 'v':
- case 's':
- {
- if (!valobj)
- break;
-
- if (log)
- log->Printf("[Debugger::FormatPrompt] initial string: %s",var_name_begin);
-
- // check for *var and *svar
- if (*var_name_begin == '*')
- {
- do_deref_pointer = true;
- var_name_begin++;
- if (log)
- log->Printf("[Debugger::FormatPrompt] found a deref, new string is: %s",var_name_begin);
- }
-
- if (*var_name_begin == 's')
- {
- if (!valobj->IsSynthetic())
- valobj = valobj->GetSyntheticValue().get();
- if (!valobj)
- break;
- var_name_begin++;
- if (log)
- log->Printf("[Debugger::FormatPrompt] found a synthetic, new string is: %s",var_name_begin);
- }
-
- // should be a 'v' by now
- if (*var_name_begin != 'v')
- break;
-
- if (log)
- log->Printf("[Debugger::FormatPrompt] string I am working with: %s",var_name_begin);
-
- ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
- ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
- ValueObject::GetValueForExpressionPathOptions options;
- options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
- ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eValueObjectRepresentationStyleSummary;
- ValueObject* target = NULL;
- Format custom_format = eFormatInvalid;
- const char* var_name_final = NULL;
- const char* var_name_final_if_array_range = NULL;
- const char* close_bracket_position = NULL;
- int64_t index_lower = -1;
- int64_t index_higher = -1;
- bool is_array_range = false;
- const char* first_unparsed;
- bool was_plain_var = false;
- bool was_var_format = false;
- bool was_var_indexed = false;
-
- if (!valobj) break;
- // simplest case ${var}, just print valobj's value
- if (IsToken (var_name_begin, "var}"))
- {
- was_plain_var = true;
- target = valobj;
- val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
- }
- else if (IsToken (var_name_begin, "var.script:"))
- {
- var_name_begin += ::strlen("var.script:");
- std::string script_name(var_name_begin,var_name_end);
- ScriptInterpreter* script_interpreter = valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
- if (RunScriptFormatKeyword (s, script_interpreter, valobj, script_name))
- var_success = true;
- break;
- }
- else if (IsToken (var_name_begin,"var%"))
- {
- was_var_format = true;
- // this is a variable with some custom format applied to it
- const char* percent_position;
- target = valobj;
- val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
- ScanFormatDescriptor (var_name_begin,
- var_name_end,
- &var_name_final,
- &percent_position,
- &custom_format,
- &val_obj_display);
- }
- // this is ${var.something} or multiple .something nested
- else if (IsToken (var_name_begin, "var"))
- {
- if (IsToken (var_name_begin, "var["))
- was_var_indexed = true;
- const char* percent_position;
- ScanFormatDescriptor (var_name_begin,
- var_name_end,
- &var_name_final,
- &percent_position,
- &custom_format,
- &val_obj_display);
-
- const char* open_bracket_position;
- const char* separator_position;
- ScanBracketedRange (var_name_begin,
- var_name_end,
- var_name_final,
- &open_bracket_position,
- &separator_position,
- &close_bracket_position,
- &var_name_final_if_array_range,
- &index_lower,
- &index_higher);
-
- Error error;
-
- std::string expr_path(var_name_final-var_name_begin-1,0);
- memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3);
-
- if (log)
- log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
-
- target = valobj->GetValueForExpressionPath(expr_path.c_str(),
- &first_unparsed,
- &reason_to_stop,
- &final_value_type,
- options,
- &what_next).get();
-
- if (!target)
- {
- if (log)
- log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
- " final_value_type %d",
- first_unparsed, reason_to_stop, final_value_type);
- break;
- }
- else
- {
- if (log)
- log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
- " final_value_type %d",
- first_unparsed, reason_to_stop, final_value_type);
- target = target->GetQualifiedRepresentationIfAvailable(target->GetDynamicValueType(), true).get();
- }
- }
- else
- break;
-
- is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
- final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
-
- do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
-
- if (do_deref_pointer && !is_array_range)
- {
- // I have not deref-ed yet, let's do it
- // this happens when we are not going through GetValueForVariableExpressionPath
- // to get to the target ValueObject
- Error error;
- target = target->Dereference(error).get();
- if (error.Fail())
- {
- if (log)
- log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
- break;
- }
- do_deref_pointer = false;
- }
-
- if (!target)
- {
- if (log)
- log->Printf("[Debugger::FormatPrompt] could not calculate target for prompt expression");
- break;
- }
-
- // we do not want to use the summary for a bitfield of type T:n
- // if we were originally dealing with just a T - that would get
- // us into an endless recursion
- if (target->IsBitfield() && was_var_indexed)
- {
- // TODO: check for a (T:n)-specific summary - we should still obey that
- StreamString bitfield_name;
- bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
- lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
- if (!DataVisualization::GetSummaryForType(type_sp))
- val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
- }
-
- // TODO use flags for these
- const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL);
- bool is_array = (type_info_flags & eTypeIsArray) != 0;
- bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
- bool is_aggregate = target->GetClangType().IsAggregateType();
-
- if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
- {
- StreamString str_temp;
- if (log)
- log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
-
- if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
- {
- // try to use the special cases
- var_success = target->DumpPrintableRepresentation(str_temp,
- val_obj_display,
- custom_format);
- if (log)
- log->Printf("[Debugger::FormatPrompt] special cases did%s match", var_success ? "" : "n't");
-
- // should not happen
- if (var_success)
- s << str_temp.GetData();
- var_success = true;
- break;
- }
- else
- {
- if (was_plain_var) // if ${var}
- {
- s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
- }
- else if (is_pointer) // if pointer, value is the address stored
- {
- target->DumpPrintableRepresentation (s,
- val_obj_display,
- custom_format,
- ValueObject::ePrintableRepresentationSpecialCasesDisable);
- }
- var_success = true;
- break;
- }
- }
-
- // if directly trying to print ${var}, and this is an aggregate, display a nice
- // type @ location message
- if (is_aggregate && was_plain_var)
- {
- s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
- var_success = true;
- break;
- }
-
- // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
- if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
- {
- s << "<invalid use of aggregate type>";
- var_success = true;
- break;
- }
-
- if (!is_array_range)
- {
- if (log)
- log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
- var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
- }
- else
- {
- if (log)
- log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
- if (!is_array && !is_pointer)
- break;
- if (log)
- log->Printf("[Debugger::FormatPrompt] handle as array");
- const char* special_directions = NULL;
- StreamString special_directions_writer;
- if (close_bracket_position && (var_name_end-close_bracket_position > 1))
- {
- ConstString additional_data;
- additional_data.SetCStringWithLength(close_bracket_position+1, var_name_end-close_bracket_position-1);
- special_directions_writer.Printf("${%svar%s}",
- do_deref_pointer ? "*" : "",
- additional_data.GetCString());
- special_directions = special_directions_writer.GetData();
- }
-
- // let us display items index_lower thru index_higher of this array
- s.PutChar('[');
- var_success = true;
-
- if (index_higher < 0)
- index_higher = valobj->GetNumChildren() - 1;
-
- uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
-
- for (;index_lower<=index_higher;index_lower++)
- {
- ValueObject* item = ExpandIndexedExpression (target,
- index_lower,
- exe_ctx->GetFramePtr(),
- false).get();
-
- if (!item)
- {
- if (log)
- log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower);
- }
- else
- {
- if (log)
- log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions);
- }
-
- if (!special_directions)
- var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
- else
- var_success &= FormatPromptRecurse(special_directions, sc, exe_ctx, addr, s, NULL, item, function_changed, initial_function);
-
- if (--max_num_children == 0)
- {
- s.PutCString(", ...");
- break;
- }
-
- if (index_lower < index_higher)
- s.PutChar(',');
- }
- s.PutChar(']');
- }
- }
- break;
- case 'a':
- if (IsToken (var_name_begin, "addr-file-or-load}"))
- {
- print_file_addr_or_load_addr = true;
- }
- if (IsToken (var_name_begin, "addr}")
- || IsToken (var_name_begin, "addr-file-or-load}"))
- {
- if (addr && addr->IsValid())
- {
- var_success = true;
- format_addr = *addr;
- }
- }
- break;
-
- case 'p':
- if (IsToken (var_name_begin, "process."))
- {
- if (exe_ctx)
- {
- Process *process = exe_ctx->GetProcessPtr();
- if (process)
- {
- var_name_begin += ::strlen ("process.");
- if (IsTokenWithFormat (var_name_begin, "id", token_format, "%" PRIu64, exe_ctx, sc))
- {
- s.Printf(token_format.c_str(), process->GetID());
- var_success = true;
- }
- else if ((IsToken (var_name_begin, "name}")) ||
- (IsToken (var_name_begin, "file.basename}")) ||
- (IsToken (var_name_begin, "file.fullpath}")))
- {
- Module *exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module)
- {
- if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
- {
- format_file_spec.GetFilename() = exe_module->GetFileSpec().GetFilename();
- var_success = (bool)format_file_spec;
- }
- else
- {
- format_file_spec = exe_module->GetFileSpec();
- var_success = (bool)format_file_spec;
- }
- }
- }
- else if (IsToken (var_name_begin, "script:"))
- {
- var_name_begin += ::strlen("script:");
- std::string script_name(var_name_begin,var_name_end);
- ScriptInterpreter* script_interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
- if (RunScriptFormatKeyword (s, script_interpreter, process, script_name))
- var_success = true;
- }
- }
- }
- }
- break;
-
- case 't':
- if (IsToken (var_name_begin, "thread."))
- {
- if (exe_ctx)
- {
- Thread *thread = exe_ctx->GetThreadPtr();
- if (thread)
- {
- var_name_begin += ::strlen ("thread.");
- if (IsTokenWithFormat (var_name_begin, "id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
- {
- s.Printf(token_format.c_str(), thread->GetID());
- var_success = true;
- }
- else if (IsTokenWithFormat (var_name_begin, "protocol_id", token_format, "0x%4.4" PRIx64, exe_ctx, sc))
- {
- s.Printf(token_format.c_str(), thread->GetProtocolID());
- var_success = true;
- }
- else if (IsTokenWithFormat (var_name_begin, "index", token_format, "%" PRIu64, exe_ctx, sc))
- {
- s.Printf(token_format.c_str(), (uint64_t)thread->GetIndexID());
- var_success = true;
- }
- else if (IsToken (var_name_begin, "name}"))
- {
- cstr = thread->GetName();
- var_success = cstr && cstr[0];
- if (var_success)
- s.PutCString(cstr);
- }
- else if (IsToken (var_name_begin, "queue}"))
- {
- cstr = thread->GetQueueName();
- var_success = cstr && cstr[0];
- if (var_success)
- s.PutCString(cstr);
- }
- else if (IsToken (var_name_begin, "stop-reason}"))
- {
- StopInfoSP stop_info_sp = thread->GetStopInfo ();
- if (stop_info_sp && stop_info_sp->IsValid())
- {
- cstr = stop_info_sp->GetDescription();
- if (cstr && cstr[0])
- {
- s.PutCString(cstr);
- var_success = true;
- }
- }
- }
- else if (IsToken (var_name_begin, "return-value}"))
- {
- StopInfoSP stop_info_sp = thread->GetStopInfo ();
- if (stop_info_sp && stop_info_sp->IsValid())
- {
- ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
- if (return_valobj_sp)
- {
- return_valobj_sp->Dump(s);
- var_success = true;
- }
- }
- }
- else if (IsToken (var_name_begin, "completed-expression}"))
- {
- StopInfoSP stop_info_sp = thread->GetStopInfo ();
- if (stop_info_sp && stop_info_sp->IsValid())
- {
- ClangExpressionVariableSP expression_var_sp = StopInfo::GetExpressionVariable (stop_info_sp);
- if (expression_var_sp && expression_var_sp->GetValueObject())
- {
- expression_var_sp->GetValueObject()->Dump(s);
- var_success = true;
- }
- }
- }
- else if (IsToken (var_name_begin, "script:"))
- {
- var_name_begin += ::strlen("script:");
- std::string script_name(var_name_begin,var_name_end);
- ScriptInterpreter* script_interpreter = thread->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
- if (RunScriptFormatKeyword (s, script_interpreter, thread, script_name))
- var_success = true;
- }
- else if (IsToken (var_name_begin, "info."))
- {
- var_name_begin += ::strlen("info.");
- StructuredData::ObjectSP object_sp = thread->GetExtendedInfo();
- if (object_sp && object_sp->GetType() == StructuredData::Type::eTypeDictionary)
- {
- var_success = FormatThreadExtendedInfoRecurse (var_name_begin, object_sp, sc, exe_ctx, s);
- }
- }
- }
- }
- }
- else if (IsToken (var_name_begin, "target."))
- {
- // TODO: hookup properties
-// if (!target_properties_sp)
-// {
-// Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
-// if (target)
-// target_properties_sp = target->GetProperties();
-// }
-//
-// if (target_properties_sp)
-// {
-// var_name_begin += ::strlen ("target.");
-// const char *end_property = strchr(var_name_begin, '}');
-// if (end_property)
-// {
-// ConstString property_name(var_name_begin, end_property - var_name_begin);
-// std::string property_value (target_properties_sp->GetPropertyValue(property_name));
-// if (!property_value.empty())
-// {
-// s.PutCString (property_value.c_str());
-// var_success = true;
-// }
-// }
-// }
- Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
- if (target)
- {
- var_name_begin += ::strlen ("target.");
- if (IsToken (var_name_begin, "arch}"))
- {
- ArchSpec arch (target->GetArchitecture ());
- if (arch.IsValid())
- {
- s.PutCString (arch.GetArchitectureName());
- var_success = true;
- }
- }
- else if (IsToken (var_name_begin, "script:"))
- {
- var_name_begin += ::strlen("script:");
- std::string script_name(var_name_begin,var_name_end);
- ScriptInterpreter* script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
- if (RunScriptFormatKeyword (s, script_interpreter, target, script_name))
- var_success = true;
- }
- }
- }
- break;
-
- case 'm':
- if (IsToken (var_name_begin, "module."))
- {
- if (sc && sc->module_sp.get())
- {
- Module *module = sc->module_sp.get();
- var_name_begin += ::strlen ("module.");
-
- if (IsToken (var_name_begin, "file."))
- {
- if (module->GetFileSpec())
- {
- var_name_begin += ::strlen ("file.");
-
- if (IsToken (var_name_begin, "basename}"))
- {
- format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
- var_success = (bool)format_file_spec;
- }
- else if (IsToken (var_name_begin, "fullpath}"))
- {
- format_file_spec = module->GetFileSpec();
- var_success = (bool)format_file_spec;
- }
- }
- }
- }
- }
- break;
-
-
- case 'f':
- if (IsToken (var_name_begin, "file."))
- {
- if (sc && sc->comp_unit != NULL)
- {
- var_name_begin += ::strlen ("file.");
-
- if (IsToken (var_name_begin, "basename}"))
- {
- format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
- var_success = (bool)format_file_spec;
- }
- else if (IsToken (var_name_begin, "fullpath}"))
- {
- format_file_spec = *sc->comp_unit;
- var_success = (bool)format_file_spec;
- }
- }
- }
- else if (IsToken (var_name_begin, "frame."))
- {
- if (exe_ctx)
- {
- StackFrame *frame = exe_ctx->GetFramePtr();
- if (frame)
- {
- var_name_begin += ::strlen ("frame.");
- if (IsToken (var_name_begin, "index}"))
- {
- s.Printf("%u", frame->GetFrameIndex());
- var_success = true;
- }
- else if (IsToken (var_name_begin, "pc}"))
- {
- reg_kind = eRegisterKindGeneric;
- reg_num = LLDB_REGNUM_GENERIC_PC;
- var_success = true;
- }
- else if (IsToken (var_name_begin, "sp}"))
- {
- reg_kind = eRegisterKindGeneric;
- reg_num = LLDB_REGNUM_GENERIC_SP;
- var_success = true;
- }
- else if (IsToken (var_name_begin, "fp}"))
- {
- reg_kind = eRegisterKindGeneric;
- reg_num = LLDB_REGNUM_GENERIC_FP;
- var_success = true;
- }
- else if (IsToken (var_name_begin, "flags}"))
- {
- reg_kind = eRegisterKindGeneric;
- reg_num = LLDB_REGNUM_GENERIC_FLAGS;
- var_success = true;
- }
- else if (IsToken (var_name_begin, "reg."))
- {
- reg_ctx = frame->GetRegisterContext().get();
- if (reg_ctx)
- {
- var_name_begin += ::strlen ("reg.");
- if (var_name_begin < var_name_end)
- {
- std::string reg_name (var_name_begin, var_name_end);
- reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
- if (reg_info)
- var_success = true;
- }
- }
- }
- else if (IsToken (var_name_begin, "script:"))
- {
- var_name_begin += ::strlen("script:");
- std::string script_name(var_name_begin,var_name_end);
- ScriptInterpreter* script_interpreter = frame->GetThread()->GetProcess()->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
- if (RunScriptFormatKeyword (s, script_interpreter, frame, script_name))
- var_success = true;
- }
- }
- }
- }
- else if (IsToken (var_name_begin, "function."))
- {
- if (sc && (sc->function != NULL || sc->symbol != NULL))
- {
- var_name_begin += ::strlen ("function.");
- if (IsToken (var_name_begin, "id}"))
- {
- if (sc->function)
- s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
- else
- s.Printf("symbol[%u]", sc->symbol->GetID());
-
- var_success = true;
- }
- if (IsToken (var_name_begin, "changed}") && function_changed)
- {
- var_success = true;
- }
- if (IsToken (var_name_begin, "initial-function}") && initial_function)
- {
- var_success = true;
- }
- else if (IsToken (var_name_begin, "name}"))
- {
- if (sc->function)
- cstr = sc->function->GetName().AsCString (NULL);
- else if (sc->symbol)
- cstr = sc->symbol->GetName().AsCString (NULL);
- if (cstr)
- {
- s.PutCString(cstr);
-
- if (sc->block)
- {
- Block *inline_block = sc->block->GetContainingInlinedBlock ();
- if (inline_block)
- {
- const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
- if (inline_info)
- {
- s.PutCString(" [inlined] ");
- inline_info->GetName().Dump(&s);
- }
- }
- }
- var_success = true;
- }
- }
- else if (IsToken (var_name_begin, "name-without-args}"))
- {
- ConstString name;
- if (sc->function)
- name = sc->function->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
- else if (sc->symbol)
- name = sc->symbol->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
- if (name)
- {
- s.PutCString(name.GetCString());
- var_success = true;
- }
- }
- else if (IsToken (var_name_begin, "name-with-args}"))
- {
- // Print the function name with arguments in it
-
- if (sc->function)
- {
- var_success = true;
- ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
- cstr = sc->function->GetName().AsCString (NULL);
- if (cstr)
- {
- const InlineFunctionInfo *inline_info = NULL;
- VariableListSP variable_list_sp;
- bool get_function_vars = true;
- if (sc->block)
- {
- Block *inline_block = sc->block->GetContainingInlinedBlock ();
-
- if (inline_block)
- {
- get_function_vars = false;
- inline_info = sc->block->GetInlinedFunctionInfo();
- if (inline_info)
- variable_list_sp = inline_block->GetBlockVariableList (true);
- }
- }
-
- if (get_function_vars)
- {
- variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
- }
-
- if (inline_info)
- {
- s.PutCString (cstr);
- s.PutCString (" [inlined] ");
- cstr = inline_info->GetName().GetCString();
- }
-
- VariableList args;
- if (variable_list_sp)
- variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
- if (args.GetSize() > 0)
- {
- const char *open_paren = strchr (cstr, '(');
- const char *close_paren = nullptr;
- const char *generic = strchr(cstr, '<');
- // if before the arguments list begins there is a template sign
- // then scan to the end of the generic args before you try to find
- // the arguments list
- if (generic && open_paren && generic < open_paren)
- {
- int generic_depth = 1;
- ++generic;
- for (;
- *generic && generic_depth > 0;
- generic++)
- {
- if (*generic == '<')
- generic_depth++;
- if (*generic == '>')
- generic_depth--;
- }
- if (*generic)
- open_paren = strchr(generic, '(');
- else
- open_paren = nullptr;
- }
- if (open_paren)
- {
- if (IsToken (open_paren, "(anonymous namespace)"))
- {
- open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
- if (open_paren)
- close_paren = strchr (open_paren, ')');
- }
- else
- close_paren = strchr (open_paren, ')');
- }
-
- if (open_paren)
- s.Write(cstr, open_paren - cstr + 1);
- else
- {
- s.PutCString (cstr);
- s.PutChar ('(');
- }
- const size_t num_args = args.GetSize();
- for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
- {
- std::string buffer;
-
- VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
- ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
- const char *var_representation = nullptr;
- const char *var_name = var_value_sp->GetName().GetCString();
- if (var_value_sp->GetClangType().IsAggregateType() &&
- DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get()))
- {
- static StringSummaryFormat format(TypeSummaryImpl::Flags()
- .SetHideItemNames(false)
- .SetShowMembersOneLiner(true),
- "");
- format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions());
- var_representation = buffer.c_str();
- }
- else
- var_representation = var_value_sp->GetValueAsCString();
- if (arg_idx > 0)
- s.PutCString (", ");
- if (var_value_sp->GetError().Success())
- {
- if (var_representation)
- s.Printf ("%s=%s", var_name, var_representation);
- else
- s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
- }
- else
- s.Printf ("%s=<unavailable>", var_name);
- }
-
- if (close_paren)
- s.PutCString (close_paren);
- else
- s.PutChar(')');
-
- }
- else
- {
- s.PutCString(cstr);
- }
- }
- }
- else if (sc->symbol)
- {
- cstr = sc->symbol->GetName().AsCString (NULL);
- if (cstr)
- {
- s.PutCString(cstr);
- var_success = true;
- }
- }
- }
- else if (IsToken (var_name_begin, "addr-offset}")
- || IsToken (var_name_begin, "concrete-only-addr-offset-no-padding}"))
- {
- if (IsToken (var_name_begin, "concrete-only-addr-offset-no-padding}"))
- {
- addr_offset_print_with_no_padding = true;
- addr_offset_concrete_func_only = true;
- }
- var_success = addr != NULL;
- if (var_success)
- {
- format_addr = *addr;
- calculate_format_addr_function_offset = true;
- }
- }
- else if (IsToken (var_name_begin, "line-offset}"))
- {
- var_success = sc->line_entry.range.GetBaseAddress().IsValid();
- if (var_success)
- {
- format_addr = sc->line_entry.range.GetBaseAddress();
- calculate_format_addr_function_offset = true;
- }
- }
- else if (IsToken (var_name_begin, "pc-offset}"))
- {
- StackFrame *frame = exe_ctx->GetFramePtr();
- var_success = frame != NULL;
- if (var_success)
- {
- format_addr = frame->GetFrameCodeAddress();
- calculate_format_addr_function_offset = true;
- }
- }
- }
- }
- break;
-
- case 'l':
- if (IsToken (var_name_begin, "line."))
- {
- if (sc && sc->line_entry.IsValid())
- {
- var_name_begin += ::strlen ("line.");
- if (IsToken (var_name_begin, "file."))
- {
- var_name_begin += ::strlen ("file.");
-
- if (IsToken (var_name_begin, "basename}"))
- {
- format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
- var_success = (bool)format_file_spec;
- }
- else if (IsToken (var_name_begin, "fullpath}"))
- {
- format_file_spec = sc->line_entry.file;
- var_success = (bool)format_file_spec;
- }
- }
- else if (IsTokenWithFormat (var_name_begin, "number", token_format, "%" PRIu64, exe_ctx, sc))
- {
- var_success = true;
- s.Printf(token_format.c_str(), (uint64_t)sc->line_entry.line);
- }
- else if ((IsToken (var_name_begin, "start-addr}")) ||
- (IsToken (var_name_begin, "end-addr}")))
- {
- var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
- if (var_success)
- {
- format_addr = sc->line_entry.range.GetBaseAddress();
- if (var_name_begin[0] == 'e')
- format_addr.Slide (sc->line_entry.range.GetByteSize());
- }
- }
- }
- }
- break;
- case 'c':
- if (IsToken (var_name_begin, "current-pc-arrow"))
- {
- if (addr && exe_ctx && exe_ctx->GetFramePtr())
- {
- RegisterContextSP reg_ctx = exe_ctx->GetFramePtr()->GetRegisterContextSP();
- if (reg_ctx.get())
- {
- addr_t pc_loadaddr = reg_ctx->GetPC();
- if (pc_loadaddr != LLDB_INVALID_ADDRESS)
- {
- Address pc;
- pc.SetLoadAddress (pc_loadaddr, exe_ctx->GetTargetPtr());
- if (pc == *addr)
- {
- s.Printf ("-> ");
- var_success = true;
- }
- }
- }
- if (var_success == false)
- {
- s.Printf(" ");
- var_success = true;
- }
- }
- var_success = true;
- }
- break;
- }
-
- if (var_success)
- {
- // If format addr is valid, then we need to print an address
- if (reg_num != LLDB_INVALID_REGNUM)
- {
- StackFrame *frame = exe_ctx->GetFramePtr();
- // We have a register value to display...
- if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
- {
- format_addr = frame->GetFrameCodeAddress();
- }
- else
- {
- if (reg_ctx == NULL)
- reg_ctx = frame->GetRegisterContext().get();
-
- if (reg_ctx)
- {
- if (reg_kind != kNumRegisterKinds)
- reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
- reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
- var_success = reg_info != NULL;
- }
- }
- }
-
- if (reg_info != NULL)
- {
- RegisterValue reg_value;
- var_success = reg_ctx->ReadRegister (reg_info, reg_value);
- if (var_success)
- {
- reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
- }
- }
-
- if (format_file_spec)
- {
- s << format_file_spec;
- }
-
- // If format addr is valid, then we need to print an address
- if (format_addr.IsValid())
- {
- var_success = false;
-
- if (calculate_format_addr_function_offset)
- {
- Address func_addr;
-
- if (sc)
- {
- if (sc->function)
- {
- func_addr = sc->function->GetAddressRange().GetBaseAddress();
- if (sc->block && addr_offset_concrete_func_only == false)
- {
- // Check to make sure we aren't in an inline
- // function. If we are, use the inline block
- // range that contains "format_addr" since
- // blocks can be discontiguous.
- Block *inline_block = sc->block->GetContainingInlinedBlock ();
- AddressRange inline_range;
- if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
- func_addr = inline_range.GetBaseAddress();
- }
- }
- else if (sc->symbol && sc->symbol->ValueIsAddress())
- func_addr = sc->symbol->GetAddress();
- }
-
- if (func_addr.IsValid())
- {
- const char *addr_offset_padding = " ";
- if (addr_offset_print_with_no_padding)
- {
- addr_offset_padding = "";
- }
- if (func_addr.GetSection() == format_addr.GetSection())
- {
- addr_t func_file_addr = func_addr.GetFileAddress();
- addr_t addr_file_addr = format_addr.GetFileAddress();
- if (addr_file_addr > func_file_addr)
- s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_file_addr - func_file_addr);
- else if (addr_file_addr < func_file_addr)
- s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_file_addr - addr_file_addr);
- var_success = true;
- }
- else
- {
- Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
- if (target)
- {
- addr_t func_load_addr = func_addr.GetLoadAddress (target);
- addr_t addr_load_addr = format_addr.GetLoadAddress (target);
- if (addr_load_addr > func_load_addr)
- s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_load_addr - func_load_addr);
- else if (addr_load_addr < func_load_addr)
- s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_load_addr - addr_load_addr);
- var_success = true;
- }
- }
- }
- }
- else
- {
- Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
- addr_t vaddr = LLDB_INVALID_ADDRESS;
- if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
- vaddr = format_addr.GetLoadAddress (target);
- if (vaddr == LLDB_INVALID_ADDRESS)
- vaddr = format_addr.GetFileAddress ();
-
- if (vaddr != LLDB_INVALID_ADDRESS)
- {
- int addr_width = 0;
- if (exe_ctx && target)
- {
- addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
- }
- if (addr_width == 0)
- addr_width = 16;
- if (print_file_addr_or_load_addr)
- {
- format_addr.Dump (&s, exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, 0);
- }
- else
- {
- s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
- }
- var_success = true;
- }
- }
- }
- }
-
- if (var_success == false)
- success = false;
- }
- p = var_name_end;
- }
- else
- break;
- }
- else
- {
- // We got a dollar sign with no '{' after it, it must just be a dollar sign
- s.PutChar(*p);
- }
- }
- else if (*p == '\\')
- {
- ++p; // skip the slash
- switch (*p)
- {
- case 'a': s.PutChar ('\a'); break;
- case 'b': s.PutChar ('\b'); break;
- case 'f': s.PutChar ('\f'); break;
- case 'n': s.PutChar ('\n'); break;
- case 'r': s.PutChar ('\r'); break;
- case 't': s.PutChar ('\t'); break;
- case 'v': s.PutChar ('\v'); break;
- case '\'': s.PutChar ('\''); break;
- case '\\': s.PutChar ('\\'); break;
- case '0':
- // 1 to 3 octal chars
- {
- // Make a string that can hold onto the initial zero char,
- // up to 3 octal digits, and a terminating NULL.
- char oct_str[5] = { 0, 0, 0, 0, 0 };
-
- int i;
- for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
- oct_str[i] = p[i];
-
- // We don't want to consume the last octal character since
- // the main for loop will do this for us, so we advance p by
- // one less than i (even if i is zero)
- p += i - 1;
- unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
- if (octal_value <= UINT8_MAX)
- {
- s.PutChar((char)octal_value);
- }
- }
- break;
-
- case 'x':
- // hex number in the format
- if (isxdigit(p[1]))
- {
- ++p; // Skip the 'x'
-
- // Make a string that can hold onto two hex chars plus a
- // NULL terminator
- char hex_str[3] = { 0,0,0 };
- hex_str[0] = *p;
- if (isxdigit(p[1]))
- {
- ++p; // Skip the first of the two hex chars
- hex_str[1] = *p;
- }
-
- unsigned long hex_value = strtoul (hex_str, NULL, 16);
- if (hex_value <= UINT8_MAX)
- s.PutChar ((char)hex_value);
- }
- else
- {
- s.PutChar('x');
- }
- break;
-
- default:
- // Just desensitize any other character by just printing what
- // came after the '\'
- s << *p;
- break;
-
- }
-
- }
- }
- if (end)
- *end = p;
- return success;
-}
-
bool
-Debugger::FormatPrompt
-(
- const char *format,
- const SymbolContext *sc,
- const ExecutionContext *exe_ctx,
- const Address *addr,
- Stream &s,
- ValueObject* valobj
-)
-{
- bool use_color = exe_ctx ? exe_ctx->GetTargetRef().GetDebugger().GetUseColor() : true;
- std::string format_str = lldb_utility::ansi::FormatAnsiTerminalCodes (format, use_color);
- if (format_str.length())
- format = format_str.c_str();
- return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, valobj, false, false);
-}
-
-bool
-Debugger::FormatDisassemblerAddress (const char *format,
+Debugger::FormatDisassemblerAddress (const FormatEntity::Entry *format,
const SymbolContext *sc,
const SymbolContext *prev_sc,
const ExecutionContext *exe_ctx,
const Address *addr,
Stream &s)
{
- if (format == NULL && exe_ctx != NULL && exe_ctx->HasTargetScope())
+ FormatEntity::Entry format_entry;
+
+ if (format == NULL)
{
- format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
+ if (exe_ctx != NULL && exe_ctx->HasTargetScope())
+ format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
+ if (format == NULL)
+ {
+ FormatEntity::Parse("${addr}: ", format_entry);
+ format = &format_entry;
+ }
}
bool function_changed = false;
bool initial_function = false;
@@ -2930,7 +1276,7 @@ Debugger::FormatDisassemblerAddress (const char *format,
{
initial_function = true;
}
- return FormatPromptRecurse (format, sc, exe_ctx, addr, s, NULL, NULL, function_changed, initial_function);
+ return FormatEntity::Format(*format, s, sc, exe_ctx, addr, NULL, function_changed, initial_function);
}
diff --git a/source/Core/Disassembler.cpp b/source/Core/Disassembler.cpp
index 649f0c5bcb26..14fbee149a52 100644
--- a/source/Core/Disassembler.cpp
+++ b/source/Core/Disassembler.cpp
@@ -471,12 +471,7 @@ Disassembler::PrintInstructions
}
const bool show_bytes = (options & eOptionShowBytes) != 0;
- const char *disassembly_format = "${addr-file-or-load}: ";
- if (exe_ctx.HasTargetScope())
- {
- disassembly_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat ();
- }
- inst->Dump (&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc, &prev_sc, disassembly_format);
+ inst->Dump (&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc, &prev_sc, NULL);
strm.EOL();
}
else
@@ -566,7 +561,7 @@ Instruction::Dump (lldb_private::Stream *s,
const ExecutionContext* exe_ctx,
const SymbolContext *sym_ctx,
const SymbolContext *prev_sym_ctx,
- const char *disassembly_addr_format_spec)
+ const FormatEntity::Entry *disassembly_addr_format)
{
size_t opcode_column_width = 7;
const size_t operand_column_width = 25;
@@ -577,7 +572,7 @@ Instruction::Dump (lldb_private::Stream *s,
if (show_address)
{
- Debugger::FormatDisassemblerAddress (disassembly_addr_format_spec, sym_ctx, prev_sym_ctx, exe_ctx, &m_address, ss);
+ Debugger::FormatDisassemblerAddress (disassembly_addr_format, sym_ctx, prev_sym_ctx, exe_ctx, &m_address, ss);
}
if (show_bytes)
@@ -985,18 +980,26 @@ InstructionList::Dump (Stream *s,
{
const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
collection::const_iterator pos, begin, end;
- const char *disassemble_format = "${addr-file-or-load}: ";
- if (exe_ctx)
+
+ const FormatEntity::Entry *disassembly_format = NULL;
+ FormatEntity::Entry format;
+ if (exe_ctx && exe_ctx->HasTargetScope())
+ {
+ disassembly_format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat ();
+ }
+ else
{
- disassemble_format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat ();
+ FormatEntity::Parse("${addr}: ", format);
+ disassembly_format = &format;
}
+
for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
pos != end;
++pos)
{
if (pos != begin)
s->EOL();
- (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, NULL, NULL, disassemble_format);
+ (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, NULL, NULL, disassembly_format);
}
}
@@ -1169,6 +1172,24 @@ Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) :
m_flavor.assign("default");
else
m_flavor.assign(flavor);
+
+ // If this is an arm variant that can only include thumb (T16, T32)
+ // instructions, force the arch triple to be "thumbv.." instead of
+ // "armv..."
+ if (arch.GetTriple().getArch() == llvm::Triple::arm
+ && (arch.GetCore() == ArchSpec::Core::eCore_arm_armv7m
+ || arch.GetCore() == ArchSpec::Core::eCore_arm_armv7em
+ || arch.GetCore() == ArchSpec::Core::eCore_arm_armv6m))
+ {
+ std::string thumb_arch_name (arch.GetTriple().getArchName().str());
+ // Replace "arm" with "thumb" so we get all thumb variants correct
+ if (thumb_arch_name.size() > 3)
+ {
+ thumb_arch_name.erase(0, 3);
+ thumb_arch_name.insert(0, "thumb");
+ }
+ m_arch.SetTriple (thumb_arch_name.c_str());
+ }
}
//----------------------------------------------------------------------
diff --git a/source/Core/Error.cpp b/source/Core/Error.cpp
index 03cfd41b288d..5b0bbe273603 100644
--- a/source/Core/Error.cpp
+++ b/source/Core/Error.cpp
@@ -146,7 +146,7 @@ void
Error::Clear ()
{
m_code = 0;
- m_type = eErrorTypeGeneric;
+ m_type = eErrorTypeInvalid;
m_string.clear();
}
diff --git a/source/Core/FormatEntity.cpp b/source/Core/FormatEntity.cpp
new file mode 100644
index 000000000000..48b2c2ddbf72
--- /dev/null
+++ b/source/Core/FormatEntity.cpp
@@ -0,0 +1,2511 @@
+//===-- FormatEntity.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringRef.h"
+
+#include "lldb/Core/FormatEntity.h"
+
+#include "lldb/Core/Address.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectVariable.h"
+#include "lldb/DataFormatters/DataVisualization.h"
+#include "lldb/DataFormatters/FormatManager.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/LineEntry.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/SectionLoadList.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/AnsiTerminal.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+enum FileKind
+{
+ FileError = 0,
+ Basename,
+ Dirname,
+ Fullpath
+};
+
+#define ENTRY(n,t,f) { n, NULL, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0,0,NULL, false}
+#define ENTRY_VALUE(n,t,f,v) { n, NULL, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, v,0,NULL, false}
+#define ENTRY_CHILDREN(n,t,f,c) { n, NULL, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0,llvm::array_lengthof(c),c, false}
+#define ENTRY_CHILDREN_KEEP_SEP(n,t,f,c) { n, NULL, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0,llvm::array_lengthof(c),c, true}
+#define ENTRY_STRING(n,s) { n, s, FormatEntity::Entry::Type::InsertString, FormatEntity::Entry::FormatType::None, 0,0, NULL, false}
+static FormatEntity::Entry::Definition g_string_entry[] =
+{
+ ENTRY("*", ParentString, None)
+};
+
+static FormatEntity::Entry::Definition g_addr_entries[] =
+{
+ ENTRY ("load", AddressLoad , UInt64),
+ ENTRY ("file", AddressFile , UInt64),
+ ENTRY ("load", AddressLoadOrFile, UInt64),
+};
+
+static FormatEntity::Entry::Definition g_file_child_entries[] =
+{
+ ENTRY_VALUE("basename", ParentNumber, CString, FileKind::Basename),
+ ENTRY_VALUE("dirname", ParentNumber, CString, FileKind::Dirname),
+ ENTRY_VALUE("fullpath", ParentNumber, CString, FileKind::Fullpath)
+};
+
+static FormatEntity::Entry::Definition g_frame_child_entries[] =
+{
+
+ ENTRY ("index", FrameIndex , UInt32),
+ ENTRY ("pc" , FrameRegisterPC , UInt64),
+ ENTRY ("fp" , FrameRegisterFP , UInt64),
+ ENTRY ("sp" , FrameRegisterSP , UInt64),
+ ENTRY ("flags", FrameRegisterFlags, UInt64),
+ ENTRY_CHILDREN ("reg", FrameRegisterByName, UInt64, g_string_entry),
+};
+
+static FormatEntity::Entry::Definition g_function_child_entries[] =
+{
+ ENTRY ("id" , FunctionID , UInt64),
+ ENTRY ("name" , FunctionName , CString),
+ ENTRY ("name-without-args" , FunctionNameNoArgs , CString),
+ ENTRY ("name-with-args" , FunctionNameWithArgs , CString),
+ ENTRY ("addr-offset" , FunctionAddrOffset , UInt64),
+ ENTRY ("concrete-only-addr-offset-no-padding", FunctionAddrOffsetConcrete, UInt64),
+ ENTRY ("line-offset" , FunctionLineOffset , UInt64),
+ ENTRY ("pc-offset" , FunctionPCOffset , UInt64)
+};
+
+static FormatEntity::Entry::Definition g_line_child_entries[] =
+{
+ ENTRY_CHILDREN("file", LineEntryFile , None , g_file_child_entries),
+ ENTRY("number" , LineEntryLineNumber , UInt32),
+ ENTRY("start-addr" , LineEntryStartAddress, UInt64),
+ ENTRY("end-addr" , LineEntryEndAddress , UInt64),
+};
+
+static FormatEntity::Entry::Definition g_module_child_entries[] =
+{
+ ENTRY_CHILDREN("file", ModuleFile, None, g_file_child_entries),
+};
+
+static FormatEntity::Entry::Definition g_process_child_entries[] =
+{
+ ENTRY ( "id" , ProcessID , UInt64 ),
+ ENTRY_VALUE ( "name" , ProcessFile , CString , FileKind::Basename),
+ ENTRY_CHILDREN ( "file" , ProcessFile , None , g_file_child_entries),
+};
+
+static FormatEntity::Entry::Definition g_svar_child_entries[] =
+{
+ ENTRY ( "*" , ParentString , None)
+};
+
+static FormatEntity::Entry::Definition g_var_child_entries[] =
+{
+ ENTRY ( "*" , ParentString , None)
+};
+
+static FormatEntity::Entry::Definition g_thread_child_entries[] =
+{
+ ENTRY ( "id" , ThreadID , UInt64 ),
+ ENTRY ( "protocol_id" , ThreadProtocolID , UInt64 ),
+ ENTRY ( "index" , ThreadIndexID , UInt32 ),
+ ENTRY_CHILDREN ( "info" , ThreadInfo , None , g_string_entry),
+ ENTRY ( "queue" , ThreadQueue , CString ),
+ ENTRY ( "name" , ThreadName , CString ),
+ ENTRY ( "stop-reason" , ThreadStopReason , CString ),
+ ENTRY ( "return-value" , ThreadReturnValue , CString ),
+ ENTRY ( "completed-expression", ThreadCompletedExpression , CString ),
+};
+
+static FormatEntity::Entry::Definition g_target_child_entries[] =
+{
+ ENTRY ( "arch" , TargetArch , CString ),
+};
+
+#define _TO_STR2(_val) #_val
+#define _TO_STR(_val) _TO_STR2(_val)
+
+static FormatEntity::Entry::Definition g_ansi_fg_entries[] =
+{
+ ENTRY_STRING ("black" , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END),
+ ENTRY_STRING ("red" , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END),
+ ENTRY_STRING ("green" , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END),
+ ENTRY_STRING ("yellow" , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END),
+ ENTRY_STRING ("blue" , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END),
+ ENTRY_STRING ("purple" , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END),
+ ENTRY_STRING ("cyan" , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END),
+ ENTRY_STRING ("white" , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END),
+};
+
+static FormatEntity::Entry::Definition g_ansi_bg_entries[] =
+{
+ ENTRY_STRING ("black" , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END),
+ ENTRY_STRING ("red" , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END),
+ ENTRY_STRING ("green" , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END),
+ ENTRY_STRING ("yellow" , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END),
+ ENTRY_STRING ("blue" , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END),
+ ENTRY_STRING ("purple" , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END),
+ ENTRY_STRING ("cyan" , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END),
+ ENTRY_STRING ("white" , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END),
+};
+
+static FormatEntity::Entry::Definition g_ansi_entries[] =
+{
+ ENTRY_CHILDREN ( "fg" , Invalid , None , g_ansi_fg_entries),
+ ENTRY_CHILDREN ( "bg" , Invalid , None , g_ansi_bg_entries),
+ ENTRY_STRING ( "normal" , ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END),
+ ENTRY_STRING ( "bold" , ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END),
+ ENTRY_STRING ( "faint" , ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END),
+ ENTRY_STRING ( "italic" , ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END),
+ ENTRY_STRING ( "underline" , ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END),
+ ENTRY_STRING ( "slow-blink" , ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END),
+ ENTRY_STRING ( "fast-blink" , ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END),
+ ENTRY_STRING ( "negative" , ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END),
+ ENTRY_STRING ( "conceal" , ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END),
+ ENTRY_STRING ( "crossed-out" , ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END),
+
+};
+
+static FormatEntity::Entry::Definition g_script_child_entries[] =
+{
+ ENTRY ( "frame" , ScriptFrame , None),
+ ENTRY ( "process" , ScriptProcess , None),
+ ENTRY ( "target" , ScriptTarget , None),
+ ENTRY ( "thread" , ScriptThread , None),
+ ENTRY ( "var" , ScriptVariable , None),
+ ENTRY ( "svar" , ScriptVariableSynthetic , None),
+ ENTRY ( "thread" , ScriptThread , None),
+};
+
+static FormatEntity::Entry::Definition g_top_level_entries[] =
+{
+ ENTRY_CHILDREN ("addr" , AddressLoadOrFile , UInt64 , g_addr_entries),
+ ENTRY ("addr-file-or-load" , AddressLoadOrFile , UInt64 ),
+ ENTRY_CHILDREN ("ansi" , Invalid , None , g_ansi_entries),
+ ENTRY ("current-pc-arrow" , CurrentPCArrow , CString ),
+ ENTRY_CHILDREN ("file" , File , CString , g_file_child_entries),
+ ENTRY_CHILDREN ("frame" , Invalid , None , g_frame_child_entries),
+ ENTRY_CHILDREN ("function" , Invalid , None , g_function_child_entries),
+ ENTRY_CHILDREN ("line" , Invalid , None , g_line_child_entries),
+ ENTRY_CHILDREN ("module" , Invalid , None , g_module_child_entries),
+ ENTRY_CHILDREN ("process" , Invalid , None , g_process_child_entries),
+ ENTRY_CHILDREN ("script" , Invalid , None , g_script_child_entries),
+ ENTRY_CHILDREN_KEEP_SEP ("svar" , VariableSynthetic , None , g_svar_child_entries),
+ ENTRY_CHILDREN ("thread" , Invalid , None , g_thread_child_entries),
+ ENTRY_CHILDREN ("target" , Invalid , None , g_target_child_entries),
+ ENTRY_CHILDREN_KEEP_SEP ("var" , Variable , None , g_var_child_entries),
+};
+
+static FormatEntity::Entry::Definition g_root = ENTRY_CHILDREN ("<root>", Root, None, g_top_level_entries);
+
+
+FormatEntity::Entry::Entry (llvm::StringRef s) :
+ string (s.data(), s.size()),
+ printf_format (),
+ children (),
+ definition (NULL),
+ type (Type::String),
+ fmt (lldb::eFormatDefault),
+ number (0),
+ deref (false)
+{
+}
+
+FormatEntity::Entry::Entry (char ch) :
+ string (1, ch),
+ printf_format (),
+ children (),
+ definition (NULL),
+ type (Type::String),
+ fmt (lldb::eFormatDefault),
+ number (0),
+ deref (false)
+{
+}
+
+void
+FormatEntity::Entry::AppendChar (char ch)
+{
+ if (children.empty() || children.back().type != Entry::Type::String)
+ children.push_back(Entry(ch));
+ else
+ children.back().string.append(1, ch);
+}
+
+void
+FormatEntity::Entry::AppendText (const llvm::StringRef &s)
+{
+ if (children.empty() || children.back().type != Entry::Type::String)
+ children.push_back(Entry(s));
+ else
+ children.back().string.append(s.data(), s.size());
+}
+
+void
+FormatEntity::Entry::AppendText (const char *cstr)
+{
+ return AppendText (llvm::StringRef(cstr));
+}
+
+
+Error
+FormatEntity::Parse (const llvm::StringRef &format_str, Entry &entry)
+{
+ entry.Clear();
+ entry.type = Entry::Type::Root;
+ llvm::StringRef modifiable_format (format_str);
+ return ParseInternal (modifiable_format, entry, 0);
+}
+
+#define ENUM_TO_CSTR(eee) case FormatEntity::Entry::Type::eee: return #eee
+
+const char *
+FormatEntity::Entry::TypeToCString (Type t)
+{
+ switch (t)
+ {
+ ENUM_TO_CSTR(Invalid);
+ ENUM_TO_CSTR(ParentNumber);
+ ENUM_TO_CSTR(ParentString);
+ ENUM_TO_CSTR(InsertString);
+ ENUM_TO_CSTR(Root);
+ ENUM_TO_CSTR(String);
+ ENUM_TO_CSTR(Scope);
+ ENUM_TO_CSTR(Variable);
+ ENUM_TO_CSTR(VariableSynthetic);
+ ENUM_TO_CSTR(ScriptVariable);
+ ENUM_TO_CSTR(ScriptVariableSynthetic);
+ ENUM_TO_CSTR(AddressLoad);
+ ENUM_TO_CSTR(AddressFile);
+ ENUM_TO_CSTR(AddressLoadOrFile);
+ ENUM_TO_CSTR(ProcessID);
+ ENUM_TO_CSTR(ProcessFile);
+ ENUM_TO_CSTR(ScriptProcess);
+ ENUM_TO_CSTR(ThreadID);
+ ENUM_TO_CSTR(ThreadProtocolID);
+ ENUM_TO_CSTR(ThreadIndexID);
+ ENUM_TO_CSTR(ThreadName);
+ ENUM_TO_CSTR(ThreadQueue);
+ ENUM_TO_CSTR(ThreadStopReason);
+ ENUM_TO_CSTR(ThreadReturnValue);
+ ENUM_TO_CSTR(ThreadCompletedExpression);
+ ENUM_TO_CSTR(ScriptThread);
+ ENUM_TO_CSTR(ThreadInfo);
+ ENUM_TO_CSTR(TargetArch);
+ ENUM_TO_CSTR(ScriptTarget);
+ ENUM_TO_CSTR(ModuleFile);
+ ENUM_TO_CSTR(File);
+ ENUM_TO_CSTR(FrameIndex);
+ ENUM_TO_CSTR(FrameRegisterPC);
+ ENUM_TO_CSTR(FrameRegisterSP);
+ ENUM_TO_CSTR(FrameRegisterFP);
+ ENUM_TO_CSTR(FrameRegisterFlags);
+ ENUM_TO_CSTR(FrameRegisterByName);
+ ENUM_TO_CSTR(ScriptFrame);
+ ENUM_TO_CSTR(FunctionID);
+ ENUM_TO_CSTR(FunctionDidChange);
+ ENUM_TO_CSTR(FunctionInitialFunction);
+ ENUM_TO_CSTR(FunctionName);
+ ENUM_TO_CSTR(FunctionNameWithArgs);
+ ENUM_TO_CSTR(FunctionNameNoArgs);
+ ENUM_TO_CSTR(FunctionAddrOffset);
+ ENUM_TO_CSTR(FunctionAddrOffsetConcrete);
+ ENUM_TO_CSTR(FunctionLineOffset);
+ ENUM_TO_CSTR(FunctionPCOffset);
+ ENUM_TO_CSTR(LineEntryFile);
+ ENUM_TO_CSTR(LineEntryLineNumber);
+ ENUM_TO_CSTR(LineEntryStartAddress);
+ ENUM_TO_CSTR(LineEntryEndAddress);
+ ENUM_TO_CSTR(CurrentPCArrow);
+ }
+ return "???";
+}
+
+#undef ENUM_TO_CSTR
+
+void
+FormatEntity::Entry::Dump (Stream &s, int depth) const
+{
+ s.Printf ("%*.*s%-20s: ", depth * 2, depth * 2, "", TypeToCString(type));
+ if (fmt != eFormatDefault)
+ s.Printf ("lldb-format = %s, ", FormatManager::GetFormatAsCString (fmt));
+ if (!string.empty())
+ s.Printf ("string = \"%s\"", string.c_str());
+ if (!printf_format.empty())
+ s.Printf ("printf_format = \"%s\"", printf_format.c_str());
+ if (number != 0)
+ s.Printf ("number = %" PRIu64 " (0x%" PRIx64 "), ", number, number);
+ if (deref)
+ s.Printf ("deref = true, ");
+ s.EOL();
+ for (const auto &child : children)
+ {
+ child.Dump(s, depth + 1);
+ }
+}
+
+
+template <typename T>
+static bool RunScriptFormatKeyword(Stream &s,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ T t,
+ const char *script_function_name)
+{
+ Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
+
+ if (target)
+ {
+ ScriptInterpreter *script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+ if (script_interpreter)
+ {
+ Error error;
+ std::string script_output;
+
+ if (script_interpreter->RunScriptFormatKeyword(script_function_name, t, script_output, error) && error.Success())
+ {
+ s.Printf("%s", script_output.c_str());
+ return true;
+ }
+ else
+ {
+ s.Printf("<error: %s>",error.AsCString());
+ }
+ }
+ }
+ return false;
+}
+
+static bool
+DumpAddress (Stream &s,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ const Address &addr,
+ bool print_file_addr_or_load_addr)
+{
+ Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
+ addr_t vaddr = LLDB_INVALID_ADDRESS;
+ if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
+ vaddr = addr.GetLoadAddress (target);
+ if (vaddr == LLDB_INVALID_ADDRESS)
+ vaddr = addr.GetFileAddress ();
+
+ if (vaddr != LLDB_INVALID_ADDRESS)
+ {
+ int addr_width = 0;
+ if (exe_ctx && target)
+ {
+ addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
+ }
+ if (addr_width == 0)
+ addr_width = 16;
+ if (print_file_addr_or_load_addr)
+ {
+ ExecutionContextScope *exe_scope = NULL;
+ if (exe_ctx)
+ exe_scope = exe_ctx->GetBestExecutionContextScope();
+ addr.Dump (&s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, 0);
+ }
+ else
+ {
+ s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
+ }
+ return true;
+ }
+ return false;
+}
+
+static bool
+DumpAddressOffsetFromFunction (Stream &s,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ const Address &format_addr,
+ bool concrete_only,
+ bool no_padding)
+{
+ if (format_addr.IsValid())
+ {
+ Address func_addr;
+
+ if (sc)
+ {
+ if (sc->function)
+ {
+ func_addr = sc->function->GetAddressRange().GetBaseAddress();
+ if (sc->block && !concrete_only)
+ {
+ // Check to make sure we aren't in an inline
+ // function. If we are, use the inline block
+ // range that contains "format_addr" since
+ // blocks can be discontiguous.
+ Block *inline_block = sc->block->GetContainingInlinedBlock ();
+ AddressRange inline_range;
+ if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
+ func_addr = inline_range.GetBaseAddress();
+ }
+ }
+ else if (sc->symbol && sc->symbol->ValueIsAddress())
+ func_addr = sc->symbol->GetAddress();
+ }
+
+ if (func_addr.IsValid())
+ {
+ const char *addr_offset_padding = no_padding ? "" : " ";
+
+ if (func_addr.GetSection() == format_addr.GetSection())
+ {
+ addr_t func_file_addr = func_addr.GetFileAddress();
+ addr_t addr_file_addr = format_addr.GetFileAddress();
+ if (addr_file_addr > func_file_addr)
+ s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_file_addr - func_file_addr);
+ else if (addr_file_addr < func_file_addr)
+ s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_file_addr - addr_file_addr);
+ return true;
+ }
+ else
+ {
+ Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
+ if (target)
+ {
+ addr_t func_load_addr = func_addr.GetLoadAddress (target);
+ addr_t addr_load_addr = format_addr.GetLoadAddress (target);
+ if (addr_load_addr > func_load_addr)
+ s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_load_addr - func_load_addr);
+ else if (addr_load_addr < func_load_addr)
+ s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_load_addr - addr_load_addr);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+static bool
+ScanBracketedRange (llvm::StringRef subpath,
+ size_t& close_bracket_index,
+ const char*& var_name_final_if_array_range,
+ int64_t& index_lower,
+ int64_t& index_higher)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+ close_bracket_index = llvm::StringRef::npos;
+ const size_t open_bracket_index = subpath.find('[');
+ if (open_bracket_index == llvm::StringRef::npos)
+ {
+ if (log)
+ log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
+ return false;
+ }
+
+ close_bracket_index = subpath.find(']', open_bracket_index + 1);
+
+ if (close_bracket_index == llvm::StringRef::npos)
+ {
+ if (log)
+ log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
+ return false;
+ }
+ else
+ {
+ var_name_final_if_array_range = subpath.data() + open_bracket_index;
+
+ if (close_bracket_index - open_bracket_index == 1)
+ {
+ if (log)
+ log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
+ index_lower = 0;
+ }
+ else
+ {
+ const size_t separator_index = subpath.find('-', open_bracket_index + 1);
+
+ if (separator_index == llvm::StringRef::npos)
+ {
+ const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
+ index_lower = ::strtoul (index_lower_cstr, NULL, 0);
+ index_higher = index_lower;
+ if (log)
+ log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", index_lower);
+ }
+ else
+ {
+ const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
+ const char *index_higher_cstr = subpath.data() + separator_index + 1;
+ index_lower = ::strtoul (index_lower_cstr, NULL, 0);
+ index_higher = ::strtoul (index_higher_cstr, NULL, 0);
+ if (log)
+ log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", index_lower, index_higher);
+ }
+ if (index_lower > index_higher && index_higher > 0)
+ {
+ if (log)
+ log->Printf("[ScanBracketedRange] swapping indices");
+ const int64_t temp = index_lower;
+ index_lower = index_higher;
+ index_higher = temp;
+ }
+ }
+ }
+ return true;
+}
+
+static bool
+DumpFile (Stream &s, const FileSpec &file, FileKind file_kind)
+{
+ switch (file_kind)
+ {
+ case FileKind::FileError:
+ break;
+
+ case FileKind::Basename:
+ if (file.GetFilename())
+ {
+ s << file.GetFilename();
+ return true;
+ }
+ break;
+
+ case FileKind::Dirname:
+ if (file.GetDirectory())
+ {
+ s << file.GetDirectory();
+ return true;
+ }
+ break;
+
+ case FileKind::Fullpath:
+ if (file)
+ {
+ s << file;
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
+static bool
+DumpRegister (Stream &s,
+ StackFrame *frame,
+ RegisterKind reg_kind,
+ uint32_t reg_num,
+ Format format)
+
+{
+ if (frame)
+ {
+ RegisterContext *reg_ctx = frame->GetRegisterContext().get();
+
+ if (reg_ctx)
+ {
+ const uint32_t lldb_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
+ if (lldb_reg_num != LLDB_INVALID_REGNUM)
+ {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (lldb_reg_num);
+ if (reg_info)
+ {
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister (reg_info, reg_value))
+ {
+ reg_value.Dump(&s, reg_info, false, false, format);
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+
+static ValueObjectSP
+ExpandIndexedExpression (ValueObject* valobj,
+ size_t index,
+ StackFrame* frame,
+ bool deref_pointer)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+ const char* ptr_deref_format = "[%d]";
+ std::string ptr_deref_buffer(10,0);
+ ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
+ if (log)
+ log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
+ const char* first_unparsed;
+ ValueObject::GetValueForExpressionPathOptions options;
+ ValueObject::ExpressionPathEndResultType final_value_type;
+ ValueObject::ExpressionPathScanEndReason reason_to_stop;
+ ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
+ ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
+ &first_unparsed,
+ &reason_to_stop,
+ &final_value_type,
+ options,
+ &what_next);
+ if (!item)
+ {
+ if (log)
+ log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
+ " final_value_type %d",
+ first_unparsed, reason_to_stop, final_value_type);
+ }
+ else
+ {
+ if (log)
+ log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
+ " final_value_type %d",
+ first_unparsed, reason_to_stop, final_value_type);
+ }
+ return item;
+}
+
+static char
+ConvertValueObjectStyleToChar(ValueObject::ValueObjectRepresentationStyle style)
+{
+ switch (style)
+ {
+ case ValueObject::eValueObjectRepresentationStyleLanguageSpecific: return '@';
+ case ValueObject::eValueObjectRepresentationStyleValue: return 'V';
+ case ValueObject::eValueObjectRepresentationStyleLocation: return 'L';
+ case ValueObject::eValueObjectRepresentationStyleSummary: return 'S';
+ case ValueObject::eValueObjectRepresentationStyleChildrenCount: return '#';
+ case ValueObject::eValueObjectRepresentationStyleType: return 'T';
+ case ValueObject::eValueObjectRepresentationStyleName: return 'N';
+ case ValueObject::eValueObjectRepresentationStyleExpressionPath: return '>';
+ }
+ return '\0';
+}
+
+static bool
+DumpValue (Stream &s,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ const FormatEntity::Entry &entry,
+ ValueObject *valobj)
+{
+ if (valobj == NULL)
+ return false;
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+ Format custom_format = eFormatInvalid;
+ ValueObject::ValueObjectRepresentationStyle val_obj_display = entry.string.empty() ? ValueObject::eValueObjectRepresentationStyleValue : ValueObject::eValueObjectRepresentationStyleSummary;
+
+ bool do_deref_pointer = entry.deref;
+ bool is_script = false;
+ switch (entry.type)
+ {
+ case FormatEntity::Entry::Type::ScriptVariable:
+ is_script = true;
+ break;
+
+ case FormatEntity::Entry::Type::Variable:
+ custom_format = entry.fmt;
+ val_obj_display = (ValueObject::ValueObjectRepresentationStyle)entry.number;
+ break;
+
+ case FormatEntity::Entry::Type::ScriptVariableSynthetic:
+ is_script = true;
+ // Fall through
+ case FormatEntity::Entry::Type::VariableSynthetic:
+ custom_format = entry.fmt;
+ val_obj_display = (ValueObject::ValueObjectRepresentationStyle)entry.number;
+ if (!valobj->IsSynthetic())
+ {
+ valobj = valobj->GetSyntheticValue().get();
+ if (valobj == nullptr)
+ return false;
+ }
+ break;
+
+ default:
+ return false;
+ }
+
+ if (valobj == NULL)
+ return false;
+
+ ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
+ ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
+ ValueObject::GetValueForExpressionPathOptions options;
+ options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().DoAllowSyntheticChildren();
+ ValueObject* target = NULL;
+ const char* var_name_final_if_array_range = NULL;
+ size_t close_bracket_index = llvm::StringRef::npos;
+ int64_t index_lower = -1;
+ int64_t index_higher = -1;
+ bool is_array_range = false;
+ const char* first_unparsed;
+ bool was_plain_var = false;
+ bool was_var_format = false;
+ bool was_var_indexed = false;
+ ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
+ ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
+
+ if (is_script)
+ {
+ return RunScriptFormatKeyword (s, sc, exe_ctx, valobj, entry.string.c_str());
+ }
+
+ llvm::StringRef subpath (entry.string);
+ // simplest case ${var}, just print valobj's value
+ if (entry.string.empty())
+ {
+ if (entry.printf_format.empty() && entry.fmt == eFormatDefault && entry.number == ValueObject::eValueObjectRepresentationStyleValue)
+ was_plain_var = true;
+ else
+ was_var_format = true;
+ target = valobj;
+ }
+ else // this is ${var.something} or multiple .something nested
+ {
+ if (entry.string[0] == '[')
+ was_var_indexed = true;
+ ScanBracketedRange (subpath,
+ close_bracket_index,
+ var_name_final_if_array_range,
+ index_lower,
+ index_higher);
+
+ Error error;
+
+ const std::string &expr_path = entry.string;
+
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
+
+ target = valobj->GetValueForExpressionPath(expr_path.c_str(),
+ &first_unparsed,
+ &reason_to_stop,
+ &final_value_type,
+ options,
+ &what_next).get();
+
+ if (!target)
+ {
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
+ " final_value_type %d",
+ first_unparsed, reason_to_stop, final_value_type);
+ return false;
+ }
+ else
+ {
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
+ " final_value_type %d",
+ first_unparsed, reason_to_stop, final_value_type);
+ target = target->GetQualifiedRepresentationIfAvailable(target->GetDynamicValueType(), true).get();
+ }
+ }
+
+
+ is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
+ final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
+
+ do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
+
+ if (do_deref_pointer && !is_array_range)
+ {
+ // I have not deref-ed yet, let's do it
+ // this happens when we are not going through GetValueForVariableExpressionPath
+ // to get to the target ValueObject
+ Error error;
+ target = target->Dereference(error).get();
+ if (error.Fail())
+ {
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
+ return false;
+ }
+ do_deref_pointer = false;
+ }
+
+ if (!target)
+ {
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] could not calculate target for prompt expression");
+ return false;
+ }
+
+ // we do not want to use the summary for a bitfield of type T:n
+ // if we were originally dealing with just a T - that would get
+ // us into an endless recursion
+ if (target->IsBitfield() && was_var_indexed)
+ {
+ // TODO: check for a (T:n)-specific summary - we should still obey that
+ StreamString bitfield_name;
+ bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
+ lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
+ if (val_obj_display == ValueObject::eValueObjectRepresentationStyleSummary && !DataVisualization::GetSummaryForType(type_sp))
+ val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
+ }
+
+ // TODO use flags for these
+ const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL);
+ bool is_array = (type_info_flags & eTypeIsArray) != 0;
+ bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
+ bool is_aggregate = target->GetClangType().IsAggregateType();
+
+ if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions
+ {
+ StreamString str_temp;
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
+
+ if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
+ {
+ // try to use the special cases
+ bool success = target->DumpPrintableRepresentation(str_temp,
+ val_obj_display,
+ custom_format);
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] special cases did%s match", success ? "" : "n't");
+
+ // should not happen
+ if (success)
+ s << str_temp.GetData();
+ return true;
+ }
+ else
+ {
+ if (was_plain_var) // if ${var}
+ {
+ s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
+ }
+ else if (is_pointer) // if pointer, value is the address stored
+ {
+ target->DumpPrintableRepresentation (s,
+ val_obj_display,
+ custom_format,
+ ValueObject::ePrintableRepresentationSpecialCasesDisable);
+ }
+ return true;
+ }
+ }
+
+ // if directly trying to print ${var}, and this is an aggregate, display a nice
+ // type @ location message
+ if (is_aggregate && was_plain_var)
+ {
+ s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
+ return true;
+ }
+
+ // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
+ if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
+ {
+ s << "<invalid use of aggregate type>";
+ return true;
+ }
+
+ if (!is_array_range)
+ {
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
+ return target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
+ }
+ else
+ {
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
+ if (!is_array && !is_pointer)
+ return false;
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] handle as array");
+ llvm::StringRef special_directions;
+ if (close_bracket_index != llvm::StringRef::npos && subpath.size() > close_bracket_index)
+ {
+ ConstString additional_data (subpath.drop_front(close_bracket_index+1));
+ StreamString special_directions_stream;
+ special_directions_stream.Printf("${%svar%s",
+ do_deref_pointer ? "*" : "",
+ additional_data.GetCString());
+
+ if (entry.fmt != eFormatDefault)
+ {
+ const char format_char = FormatManager::GetFormatAsFormatChar(entry.fmt);
+ if (format_char != '\0')
+ special_directions_stream.Printf("%%%c", format_char);
+ else
+ {
+ const char *format_cstr = FormatManager::GetFormatAsCString(entry.fmt);
+ special_directions_stream.Printf("%%%s", format_cstr);
+ }
+ }
+ else if (entry.number != 0)
+ {
+ const char style_char = ConvertValueObjectStyleToChar ((ValueObject::ValueObjectRepresentationStyle)entry.number);
+ if (style_char)
+ special_directions_stream.Printf("%%%c", style_char);
+ }
+ special_directions_stream.PutChar('}');
+ special_directions = llvm::StringRef(special_directions_stream.GetString());
+ }
+
+ // let us display items index_lower thru index_higher of this array
+ s.PutChar('[');
+
+ if (index_higher < 0)
+ index_higher = valobj->GetNumChildren() - 1;
+
+ uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
+
+ bool success = true;
+ for (int64_t index = index_lower;index<=index_higher; ++index)
+ {
+ ValueObject* item = ExpandIndexedExpression (target,
+ index,
+ exe_ctx->GetFramePtr(),
+ false).get();
+
+ if (!item)
+ {
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index);
+ }
+ else
+ {
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions.data() ? special_directions.data() : "");
+ }
+
+ if (special_directions.empty())
+ {
+ success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
+ }
+ else
+ {
+ success &= FormatEntity::FormatStringRef(special_directions, s, sc, exe_ctx, NULL, item, false, false);
+ }
+
+ if (--max_num_children == 0)
+ {
+ s.PutCString(", ...");
+ break;
+ }
+
+ if (index < index_higher)
+ s.PutChar(',');
+ }
+ s.PutChar(']');
+ return success;
+ }
+
+}
+
+static bool
+DumpRegister (Stream &s,
+ StackFrame *frame,
+ const char *reg_name,
+ Format format)
+
+{
+ if (frame)
+ {
+ RegisterContext *reg_ctx = frame->GetRegisterContext().get();
+
+ if (reg_ctx)
+ {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
+ if (reg_info)
+ {
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister (reg_info, reg_value))
+ {
+ reg_value.Dump(&s, reg_info, false, false, format);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+static bool
+FormatThreadExtendedInfoRecurse(const FormatEntity::Entry &entry,
+ const StructuredData::ObjectSP &thread_info_dictionary,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ Stream &s)
+{
+ llvm::StringRef path(entry.string);
+
+ StructuredData::ObjectSP value = thread_info_dictionary->GetObjectForDotSeparatedPath (path);
+
+ if (value.get())
+ {
+ if (value->GetType() == StructuredData::Type::eTypeInteger)
+ {
+ const char *token_format = "0x%4.4" PRIx64;
+ if (!entry.printf_format.empty())
+ token_format = entry.printf_format.c_str();
+ s.Printf(token_format, value->GetAsInteger()->GetValue());
+ return true;
+ }
+ else if (value->GetType() == StructuredData::Type::eTypeFloat)
+ {
+ s.Printf ("%f", value->GetAsFloat()->GetValue());
+ return true;
+ }
+ else if (value->GetType() == StructuredData::Type::eTypeString)
+ {
+ s.Printf("%s", value->GetAsString()->GetValue().c_str());
+ return true;
+ }
+ else if (value->GetType() == StructuredData::Type::eTypeArray)
+ {
+ if (value->GetAsArray()->GetSize() > 0)
+ {
+ s.Printf ("%zu", value->GetAsArray()->GetSize());
+ return true;
+ }
+ }
+ else if (value->GetType() == StructuredData::Type::eTypeDictionary)
+ {
+ s.Printf ("%zu", value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+static inline bool
+IsToken(const char *var_name_begin, const char *var)
+{
+ return (::strncmp (var_name_begin, var, strlen(var)) == 0);
+}
+
+bool
+FormatEntity::FormatStringRef (const llvm::StringRef &format_str,
+ Stream &s,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ const Address *addr,
+ ValueObject* valobj,
+ bool function_changed,
+ bool initial_function)
+{
+ if (!format_str.empty())
+ {
+ FormatEntity::Entry root;
+ Error error = FormatEntity::Parse(format_str, root);
+ if (error.Success())
+ {
+ return FormatEntity::Format (root,
+ s,
+ sc,
+ exe_ctx,
+ addr,
+ valobj,
+ function_changed,
+ initial_function);
+ }
+ }
+ return false;
+
+}
+bool
+FormatEntity::FormatCString (const char *format,
+ Stream &s,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ const Address *addr,
+ ValueObject* valobj,
+ bool function_changed,
+ bool initial_function)
+{
+ if (format && format[0])
+ {
+ FormatEntity::Entry root;
+ llvm::StringRef format_str(format);
+ Error error = FormatEntity::Parse(format_str, root);
+ if (error.Success())
+ {
+ return FormatEntity::Format (root,
+ s,
+ sc,
+ exe_ctx,
+ addr,
+ valobj,
+ function_changed,
+ initial_function);
+ }
+ }
+ return false;
+}
+
+bool
+FormatEntity::Format (const Entry &entry,
+ Stream &s,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ const Address *addr,
+ ValueObject* valobj,
+ bool function_changed,
+ bool initial_function)
+{
+ switch (entry.type)
+ {
+ case Entry::Type::Invalid:
+ case Entry::Type::ParentNumber: // Only used for FormatEntity::Entry::Definition encoding
+ case Entry::Type::ParentString: // Only used for FormatEntity::Entry::Definition encoding
+ case Entry::Type::InsertString: // Only used for FormatEntity::Entry::Definition encoding
+ return false;
+
+ case Entry::Type::Root:
+ for (const auto &child : entry.children)
+ {
+ if (Format (child,
+ s,
+ sc,
+ exe_ctx,
+ addr,
+ valobj,
+ function_changed,
+ initial_function) == false)
+ {
+ return false; // If any item of root fails, then the formatting fails
+ }
+ }
+ return true; // Only return true if all items succeeded
+
+ case Entry::Type::String:
+ s.PutCString(entry.string.c_str());
+ return true;
+
+ case Entry::Type::Scope:
+ {
+ StreamString scope_stream;
+ bool success = false;
+ for (const auto &child : entry.children)
+ {
+ success = Format (child, scope_stream, sc, exe_ctx, addr, valobj, function_changed, initial_function);
+ if (!success)
+ break;
+ }
+ // Only if all items in a scope succeed, then do we
+ // print the output into the main stream
+ if (success)
+ s.Write(scope_stream.GetString().data(), scope_stream.GetString().size());
+ }
+ return true; // Scopes always successfully print themselves
+
+ case Entry::Type::Variable:
+ case Entry::Type::VariableSynthetic:
+ case Entry::Type::ScriptVariable:
+ case Entry::Type::ScriptVariableSynthetic:
+ if (DumpValue(s, sc, exe_ctx, entry, valobj))
+ return true;
+ return false;
+
+ case Entry::Type::AddressFile:
+ case Entry::Type::AddressLoad:
+ case Entry::Type::AddressLoadOrFile:
+ if (addr && addr->IsValid() && DumpAddress(s, sc, exe_ctx, *addr, entry.type == Entry::Type::AddressLoadOrFile))
+ return true;
+ return false;
+
+ case Entry::Type::ProcessID:
+ if (exe_ctx)
+ {
+ Process *process = exe_ctx->GetProcessPtr();
+ if (process)
+ {
+ const char *format = "%" PRIu64;
+ if (!entry.printf_format.empty())
+ format = entry.printf_format.c_str();
+ s.Printf(format, process->GetID());
+ return true;
+ }
+ }
+ return false;
+
+ case Entry::Type::ProcessFile:
+ if (exe_ctx)
+ {
+ Process *process = exe_ctx->GetProcessPtr();
+ if (process)
+ {
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module)
+ {
+ if (DumpFile(s, exe_module->GetFileSpec(), (FileKind)entry.number))
+ return true;
+ }
+ }
+ }
+ return false;
+
+ case Entry::Type::ScriptProcess:
+ if (exe_ctx)
+ {
+ Process *process = exe_ctx->GetProcessPtr();
+ if (process)
+ return RunScriptFormatKeyword (s, sc, exe_ctx, process, entry.string.c_str());
+ }
+ return false;
+
+
+ case Entry::Type::ThreadID:
+ if (exe_ctx)
+ {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread)
+ {
+ const char *format = "0x%4.4" PRIx64;
+ if (!entry.printf_format.empty())
+ {
+ // Watch for the special "tid" format...
+ if (entry.printf_format == "tid")
+ {
+ bool handled = false;
+ Target &target = thread->GetProcess()->GetTarget();
+ ArchSpec arch (target.GetArchitecture ());
+ llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS;
+ if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux))
+ {
+ handled = true;
+ format = "%" PRIu64;
+ }
+ }
+ else
+ {
+ format = entry.printf_format.c_str();
+ }
+ }
+ s.Printf(format, thread->GetID());
+ return true;
+ }
+ }
+ return false;
+
+ case Entry::Type::ThreadProtocolID:
+ if (exe_ctx)
+ {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread)
+ {
+ const char *format = "0x%4.4" PRIx64;
+ if (!entry.printf_format.empty())
+ format = entry.printf_format.c_str();
+ s.Printf(format, thread->GetProtocolID());
+ return true;
+ }
+ }
+ return false;
+
+ case Entry::Type::ThreadIndexID:
+ if (exe_ctx)
+ {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread)
+ {
+ const char *format = "%" PRIu32;
+ if (!entry.printf_format.empty())
+ format = entry.printf_format.c_str();
+ s.Printf(format, thread->GetIndexID());
+ return true;
+ }
+ }
+ return false;
+
+ case Entry::Type::ThreadName:
+ if (exe_ctx)
+ {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread)
+ {
+ const char *cstr = thread->GetName();
+ if (cstr && cstr[0])
+ {
+ s.PutCString(cstr);
+ return true;
+ }
+ }
+ }
+ return false;
+
+ case Entry::Type::ThreadQueue:
+ if (exe_ctx)
+ {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread)
+ {
+ const char *cstr = thread->GetQueueName();
+ if (cstr && cstr[0])
+ {
+ s.PutCString(cstr);
+ return true;
+ }
+ }
+ }
+ return false;
+
+ case Entry::Type::ThreadStopReason:
+ if (exe_ctx)
+ {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread)
+ {
+ StopInfoSP stop_info_sp = thread->GetStopInfo ();
+ if (stop_info_sp && stop_info_sp->IsValid())
+ {
+ const char *cstr = stop_info_sp->GetDescription();
+ if (cstr && cstr[0])
+ {
+ s.PutCString(cstr);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+
+ case Entry::Type::ThreadReturnValue:
+ if (exe_ctx)
+ {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread)
+ {
+ StopInfoSP stop_info_sp = thread->GetStopInfo ();
+ if (stop_info_sp && stop_info_sp->IsValid())
+ {
+ ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
+ if (return_valobj_sp)
+ {
+ return_valobj_sp->Dump(s);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+
+ case Entry::Type::ThreadCompletedExpression:
+ if (exe_ctx)
+ {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread)
+ {
+ StopInfoSP stop_info_sp = thread->GetStopInfo ();
+ if (stop_info_sp && stop_info_sp->IsValid())
+ {
+ ClangExpressionVariableSP expression_var_sp = StopInfo::GetExpressionVariable (stop_info_sp);
+ if (expression_var_sp && expression_var_sp->GetValueObject())
+ {
+ expression_var_sp->GetValueObject()->Dump(s);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+
+ case Entry::Type::ScriptThread:
+ if (exe_ctx)
+ {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread)
+ return RunScriptFormatKeyword (s, sc, exe_ctx, thread, entry.string.c_str());
+ }
+ return false;
+
+ case Entry::Type::ThreadInfo:
+ if (exe_ctx)
+ {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread)
+ {
+ StructuredData::ObjectSP object_sp = thread->GetExtendedInfo();
+ if (object_sp && object_sp->GetType() == StructuredData::Type::eTypeDictionary)
+ {
+ if (FormatThreadExtendedInfoRecurse (entry, object_sp, sc, exe_ctx, s))
+ return true;
+ }
+ }
+ }
+ return false;
+
+ case Entry::Type::TargetArch:
+ if (exe_ctx)
+ {
+ Target *target = exe_ctx->GetTargetPtr();
+ if (target)
+ {
+ const ArchSpec &arch = target->GetArchitecture ();
+ if (arch.IsValid())
+ {
+ s.PutCString (arch.GetArchitectureName());
+ return true;
+ }
+ }
+ }
+ return false;
+
+ case Entry::Type::ScriptTarget:
+ if (exe_ctx)
+ {
+ Target *target = exe_ctx->GetTargetPtr();
+ if (target)
+ return RunScriptFormatKeyword (s, sc, exe_ctx, target, entry.string.c_str());
+ }
+ return false;
+
+ case Entry::Type::ModuleFile:
+ if (sc)
+ {
+ Module *module = sc->module_sp.get();
+ if (module)
+ {
+ if (DumpFile(s, module->GetFileSpec(), (FileKind)entry.number))
+ return true;
+ }
+ }
+ return false;
+
+ case Entry::Type::File:
+ if (sc)
+ {
+ CompileUnit *cu = sc->comp_unit;
+ if (cu)
+ {
+ // CompileUnit is a FileSpec
+ if (DumpFile(s, *cu, (FileKind)entry.number))
+ return true;
+ }
+ }
+ return false;
+
+ case Entry::Type::FrameIndex:
+ if (exe_ctx)
+ {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame)
+ {
+ const char *format = "%" PRIu32;
+ if (!entry.printf_format.empty())
+ format = entry.printf_format.c_str();
+ s.Printf(format, frame->GetFrameIndex());
+ return true;
+ }
+ }
+ return false;
+
+ case Entry::Type::FrameRegisterPC:
+ if (exe_ctx)
+ {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame)
+ {
+ const Address &pc_addr = frame->GetFrameCodeAddress();
+ if (pc_addr.IsValid())
+ {
+ if (DumpAddress(s, sc, exe_ctx, pc_addr, false))
+ return true;
+ }
+ }
+ }
+ return false;
+
+ case Entry::Type::FrameRegisterSP:
+ if (exe_ctx)
+ {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame)
+ {
+ if (DumpRegister (s, frame, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, (lldb::Format)entry.number))
+ return true;
+ }
+ }
+ return false;
+
+ case Entry::Type::FrameRegisterFP:
+ if (exe_ctx)
+ {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame)
+ {
+ if (DumpRegister (s, frame, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, (lldb::Format)entry.number))
+ return true;
+ }
+ }
+ return false;
+
+ case Entry::Type::FrameRegisterFlags:
+ if (exe_ctx)
+ {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame)
+ {
+ if (DumpRegister (s, frame, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, (lldb::Format)entry.number))
+ return true;
+ }
+ }
+ return false;
+
+
+ case Entry::Type::FrameRegisterByName:
+ if (exe_ctx)
+ {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame)
+ {
+ if (DumpRegister (s, frame, entry.string.c_str(), (lldb::Format)entry.number))
+ return true;
+ }
+ }
+ return false;
+
+ case Entry::Type::ScriptFrame:
+ if (exe_ctx)
+ {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame)
+ return RunScriptFormatKeyword (s, sc, exe_ctx, frame, entry.string.c_str());
+ }
+ return false;
+
+ case Entry::Type::FunctionID:
+ if (sc)
+ {
+ if (sc->function)
+ {
+ s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
+ return true;
+ }
+ else if (sc->symbol)
+ {
+ s.Printf("symbol[%u]", sc->symbol->GetID());
+ return true;
+ }
+ }
+ return false;
+
+ case Entry::Type::FunctionDidChange:
+ return function_changed;
+
+ case Entry::Type::FunctionInitialFunction:
+ return initial_function;
+
+ case Entry::Type::FunctionName:
+ {
+ const char *name = NULL;
+ if (sc->function)
+ name = sc->function->GetName().AsCString (NULL);
+ else if (sc->symbol)
+ name = sc->symbol->GetName().AsCString (NULL);
+ if (name)
+ {
+ s.PutCString(name);
+
+ if (sc->block)
+ {
+ Block *inline_block = sc->block->GetContainingInlinedBlock ();
+ if (inline_block)
+ {
+ const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
+ if (inline_info)
+ {
+ s.PutCString(" [inlined] ");
+ inline_info->GetName().Dump(&s);
+ }
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+
+ case Entry::Type::FunctionNameNoArgs:
+ {
+ ConstString name;
+ if (sc->function)
+ name = sc->function->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
+ else if (sc->symbol)
+ name = sc->symbol->GetMangled().GetName (Mangled::ePreferDemangledWithoutArguments);
+ if (name)
+ {
+ s.PutCString(name.GetCString());
+ return true;
+ }
+ }
+ return false;
+
+ case Entry::Type::FunctionNameWithArgs:
+ {
+ // Print the function name with arguments in it
+ if (sc->function)
+ {
+ ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
+ const char *cstr = sc->function->GetName().AsCString (NULL);
+ if (cstr)
+ {
+ const InlineFunctionInfo *inline_info = NULL;
+ VariableListSP variable_list_sp;
+ bool get_function_vars = true;
+ if (sc->block)
+ {
+ Block *inline_block = sc->block->GetContainingInlinedBlock ();
+
+ if (inline_block)
+ {
+ get_function_vars = false;
+ inline_info = sc->block->GetInlinedFunctionInfo();
+ if (inline_info)
+ variable_list_sp = inline_block->GetBlockVariableList (true);
+ }
+ }
+
+ if (get_function_vars)
+ {
+ variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
+ }
+
+ if (inline_info)
+ {
+ s.PutCString (cstr);
+ s.PutCString (" [inlined] ");
+ cstr = inline_info->GetName().GetCString();
+ }
+
+ VariableList args;
+ if (variable_list_sp)
+ variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
+ if (args.GetSize() > 0)
+ {
+ const char *open_paren = strchr (cstr, '(');
+ const char *close_paren = nullptr;
+ const char *generic = strchr(cstr, '<');
+ // if before the arguments list begins there is a template sign
+ // then scan to the end of the generic args before you try to find
+ // the arguments list
+ if (generic && open_paren && generic < open_paren)
+ {
+ int generic_depth = 1;
+ ++generic;
+ for (;
+ *generic && generic_depth > 0;
+ generic++)
+ {
+ if (*generic == '<')
+ generic_depth++;
+ if (*generic == '>')
+ generic_depth--;
+ }
+ if (*generic)
+ open_paren = strchr(generic, '(');
+ else
+ open_paren = nullptr;
+ }
+ if (open_paren)
+ {
+ if (IsToken (open_paren, "(anonymous namespace)"))
+ {
+ open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
+ if (open_paren)
+ close_paren = strchr (open_paren, ')');
+ }
+ else
+ close_paren = strchr (open_paren, ')');
+ }
+
+ if (open_paren)
+ s.Write(cstr, open_paren - cstr + 1);
+ else
+ {
+ s.PutCString (cstr);
+ s.PutChar ('(');
+ }
+ const size_t num_args = args.GetSize();
+ for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
+ {
+ std::string buffer;
+
+ VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
+ ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
+ const char *var_representation = nullptr;
+ const char *var_name = var_value_sp->GetName().GetCString();
+ if (var_value_sp->GetClangType().IsAggregateType() &&
+ DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get()))
+ {
+ static StringSummaryFormat format(TypeSummaryImpl::Flags()
+ .SetHideItemNames(false)
+ .SetShowMembersOneLiner(true),
+ "");
+ format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions());
+ var_representation = buffer.c_str();
+ }
+ else
+ var_representation = var_value_sp->GetValueAsCString();
+ if (arg_idx > 0)
+ s.PutCString (", ");
+ if (var_value_sp->GetError().Success())
+ {
+ if (var_representation)
+ s.Printf ("%s=%s", var_name, var_representation);
+ else
+ s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
+ }
+ else
+ s.Printf ("%s=<unavailable>", var_name);
+ }
+
+ if (close_paren)
+ s.PutCString (close_paren);
+ else
+ s.PutChar(')');
+
+ }
+ else
+ {
+ s.PutCString(cstr);
+ }
+ return true;
+ }
+ }
+ else if (sc->symbol)
+ {
+ const char *cstr = sc->symbol->GetName().AsCString (NULL);
+ if (cstr)
+ {
+ s.PutCString(cstr);
+ return true;
+ }
+ }
+ }
+ return false;
+
+ case Entry::Type::FunctionAddrOffset:
+ if (addr)
+ {
+ if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, *addr, false, false))
+ return true;
+ }
+ return false;
+
+ case Entry::Type::FunctionAddrOffsetConcrete:
+ if (addr)
+ {
+ if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, *addr, true, true))
+ return true;
+ }
+ return false;
+
+ case Entry::Type::FunctionLineOffset:
+ if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, sc->line_entry.range.GetBaseAddress(), false, false))
+ return true;
+ return false;
+
+ case Entry::Type::FunctionPCOffset:
+ if (exe_ctx)
+ {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame)
+ {
+ if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, frame->GetFrameCodeAddress(), false, false))
+ return true;
+ }
+ }
+ return false;
+
+ case Entry::Type::LineEntryFile:
+ if (sc && sc->line_entry.IsValid())
+ {
+ Module *module = sc->module_sp.get();
+ if (module)
+ {
+ if (DumpFile(s, sc->line_entry.file, (FileKind)entry.number))
+ return true;
+ }
+ }
+ return false;
+
+ case Entry::Type::LineEntryLineNumber:
+ if (sc && sc->line_entry.IsValid())
+ {
+ const char *format = "%" PRIu32;
+ if (!entry.printf_format.empty())
+ format = entry.printf_format.c_str();
+ s.Printf(format, sc->line_entry.line);
+ return true;
+ }
+ return false;
+
+ case Entry::Type::LineEntryStartAddress:
+ case Entry::Type::LineEntryEndAddress:
+ if (sc && sc->line_entry.range.GetBaseAddress().IsValid())
+ {
+ Address addr = sc->line_entry.range.GetBaseAddress();
+
+ if (entry.type == Entry::Type::LineEntryEndAddress)
+ addr.Slide(sc->line_entry.range.GetByteSize());
+ if (DumpAddress(s, sc, exe_ctx, addr, false))
+ return true;
+ }
+ return false;
+
+ case Entry::Type::CurrentPCArrow:
+ if (addr && exe_ctx && exe_ctx->GetFramePtr())
+ {
+ RegisterContextSP reg_ctx = exe_ctx->GetFramePtr()->GetRegisterContextSP();
+ if (reg_ctx.get())
+ {
+ addr_t pc_loadaddr = reg_ctx->GetPC();
+ if (pc_loadaddr != LLDB_INVALID_ADDRESS)
+ {
+ Address pc;
+ pc.SetLoadAddress (pc_loadaddr, exe_ctx->GetTargetPtr());
+ if (pc == *addr)
+ {
+ s.Printf ("-> ");
+ return true;
+ }
+ }
+ }
+ s.Printf(" ");
+ return true;
+ }
+ return false;
+ }
+ return false;
+}
+
+static bool
+DumpCommaSeparatedChildEntryNames (Stream &s, const FormatEntity::Entry::Definition *parent)
+{
+ if (parent->children)
+ {
+ const size_t n = parent->num_children;
+ for (size_t i=0; i<n; ++i)
+ {
+ if (i > 0)
+ s.PutCString(", ");
+ s.Printf ("\"%s\"", parent->children[i].name);
+ }
+ return true;
+ }
+ return false;
+}
+
+
+static Error
+ParseEntry (const llvm::StringRef &format_str,
+ const FormatEntity::Entry::Definition *parent,
+ FormatEntity::Entry &entry)
+{
+ Error error;
+
+ const size_t sep_pos = format_str.find_first_of(".[:");
+ const char sep_char = (sep_pos == llvm::StringRef::npos) ? '\0' : format_str[sep_pos];
+ llvm::StringRef key = format_str.substr(0, sep_pos);
+
+ const size_t n = parent->num_children;
+ for (size_t i=0; i<n; ++i)
+ {
+ const FormatEntity::Entry::Definition *entry_def = parent->children + i;
+ if (key.equals(entry_def->name) || entry_def->name[0] == '*')
+ {
+ llvm::StringRef value;
+ if (sep_char)
+ value = format_str.substr(sep_pos + (entry_def->keep_separator ? 0 : 1));
+ switch (entry_def->type)
+ {
+ case FormatEntity::Entry::Type::ParentString:
+ entry.string = std::move(format_str.str());
+ return error; // Success
+
+ case FormatEntity::Entry::Type::ParentNumber:
+ entry.number = entry_def->data;
+ return error; // Success
+
+ case FormatEntity::Entry::Type::InsertString:
+ entry.type = entry_def->type;
+ entry.string = entry_def->string;
+ return error; // Success
+
+ default:
+ entry.type = entry_def->type;
+ break;
+ }
+
+ if (value.empty())
+ {
+ if (entry_def->type == FormatEntity::Entry::Type::Invalid)
+ {
+ if (entry_def->children)
+ {
+ StreamString error_strm;
+ error_strm.Printf("'%s' can't be specified on its own, you must access one of its children: ", entry_def->name);
+ DumpCommaSeparatedChildEntryNames (error_strm, entry_def);
+ error.SetErrorStringWithFormat("%s", error_strm.GetString().c_str());
+ }
+ else if (sep_char == ':')
+ {
+ // Any value whose separator is a with a ':' means this value has a string argument
+ // that needs to be stored in the entry (like "${script.var:}").
+ // In this case the string value is the empty string which is ok.
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("%s", "invalid entry definitions");
+ }
+ }
+ }
+ else
+ {
+ if (entry_def->children)
+ {
+ error = ParseEntry (value, entry_def, entry);
+ }
+ else if (sep_char == ':')
+ {
+ // Any value whose separator is a with a ':' means this value has a string argument
+ // that needs to be stored in the entry (like "${script.var:modulename.function}")
+ entry.string = std::move(value.str());
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("'%s' followed by '%s' but it has no children",
+ key.str().c_str(),
+ value.str().c_str());
+ }
+ }
+ return error;
+ }
+ }
+ StreamString error_strm;
+ if (parent->type == FormatEntity::Entry::Type::Root)
+ error_strm.Printf("invalid top level item '%s'. Valid top level items are: ", key.str().c_str());
+ else
+ error_strm.Printf("invalid member '%s' in '%s'. Valid members are: ", key.str().c_str(), parent->name);
+ DumpCommaSeparatedChildEntryNames (error_strm, parent);
+ error.SetErrorStringWithFormat("%s", error_strm.GetString().c_str());
+ return error;
+}
+
+
+static const FormatEntity::Entry::Definition *
+FindEntry (const llvm::StringRef &format_str, const FormatEntity::Entry::Definition *parent, llvm::StringRef &remainder)
+{
+ Error error;
+
+ std::pair<llvm::StringRef, llvm::StringRef> p = format_str.split('.');
+ const size_t n = parent->num_children;
+ for (size_t i=0; i<n; ++i)
+ {
+ const FormatEntity::Entry::Definition *entry_def = parent->children + i;
+ if (p.first.equals(entry_def->name) || entry_def->name[0] == '*')
+ {
+ if (p.second.empty())
+ {
+ if (format_str.back() == '.')
+ remainder = format_str.drop_front(format_str.size() - 1);
+ else
+ remainder = llvm::StringRef(); // Exact match
+ return entry_def;
+ }
+ else
+ {
+ if (entry_def->children)
+ {
+ return FindEntry (p.second, entry_def, remainder);
+ }
+ else
+ {
+ remainder = p.second;
+ return entry_def;
+ }
+ }
+ }
+ }
+ remainder = format_str;
+ return parent;
+}
+
+Error
+FormatEntity::ParseInternal (llvm::StringRef &format, Entry &parent_entry, uint32_t depth)
+{
+ Error error;
+ while (!format.empty() && error.Success())
+ {
+ const size_t non_special_chars = format.find_first_of("${}\\");
+
+ if (non_special_chars == llvm::StringRef::npos)
+ {
+ // No special characters, just string bytes so add them and we are done
+ parent_entry.AppendText(format);
+ return error;
+ }
+
+ if (non_special_chars > 0)
+ {
+ // We have a special character, so add all characters before these as a plain string
+ parent_entry.AppendText(format.substr(0,non_special_chars));
+ format = format.drop_front(non_special_chars);
+ }
+
+ switch (format[0])
+ {
+ case '\0':
+ return error;
+
+ case '{':
+ {
+ format = format.drop_front(); // Skip the '{'
+ Entry scope_entry(Entry::Type::Scope);
+ error = FormatEntity::ParseInternal (format, scope_entry, depth+1);
+ if (error.Fail())
+ return error;
+ parent_entry.AppendEntry(std::move(scope_entry));
+ }
+ break;
+
+ case '}':
+ if (depth == 0)
+ error.SetErrorString("unmatched '}' character");
+ else
+ format = format.drop_front(); // Skip the '}' as we are at the end of the scope
+ return error;
+
+ case '\\':
+ {
+ format = format.drop_front(); // Skip the '\' character
+ if (format.empty())
+ {
+ error.SetErrorString("'\\' character was not followed by another character");
+ return error;
+ }
+
+ const char desens_char = format[0];
+ format = format.drop_front(); // Skip the desensitized char character
+ switch (desens_char)
+ {
+ case 'a': parent_entry.AppendChar('\a'); break;
+ case 'b': parent_entry.AppendChar('\b'); break;
+ case 'f': parent_entry.AppendChar('\f'); break;
+ case 'n': parent_entry.AppendChar('\n'); break;
+ case 'r': parent_entry.AppendChar('\r'); break;
+ case 't': parent_entry.AppendChar('\t'); break;
+ case 'v': parent_entry.AppendChar('\v'); break;
+ case '\'': parent_entry.AppendChar('\''); break;
+ case '\\': parent_entry.AppendChar('\\'); break;
+ case '0':
+ // 1 to 3 octal chars
+ {
+ // Make a string that can hold onto the initial zero char,
+ // up to 3 octal digits, and a terminating NULL.
+ char oct_str[5] = { 0, 0, 0, 0, 0 };
+
+ int i;
+ for (i=0; (format[i] >= '0' && format[i] <= '7') && i<4; ++i)
+ oct_str[i] = format[i];
+
+ // We don't want to consume the last octal character since
+ // the main for loop will do this for us, so we advance p by
+ // one less than i (even if i is zero)
+ format = format.drop_front(i);
+ unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
+ if (octal_value <= UINT8_MAX)
+ {
+ parent_entry.AppendChar((char)octal_value);
+ }
+ else
+ {
+ error.SetErrorString("octal number is larger than a single byte");
+ return error;
+ }
+ }
+ break;
+
+ case 'x':
+ // hex number in the format
+ if (isxdigit(format[0]))
+ {
+ // Make a string that can hold onto two hex chars plus a
+ // NULL terminator
+ char hex_str[3] = { 0,0,0 };
+ hex_str[0] = format[0];
+
+ format = format.drop_front();
+
+ if (isxdigit(format[0]))
+ {
+ hex_str[1] = format[0];
+ format = format.drop_front();
+ }
+
+ unsigned long hex_value = strtoul (hex_str, NULL, 16);
+ if (hex_value <= UINT8_MAX)
+ {
+ parent_entry.AppendChar((char)hex_value);
+ }
+ else
+ {
+ error.SetErrorString("hex number is larger than a single byte");
+ return error;
+ }
+ }
+ else
+ {
+ parent_entry.AppendChar(desens_char);
+ }
+ break;
+
+ default:
+ // Just desensitize any other character by just printing what
+ // came after the '\'
+ parent_entry.AppendChar(desens_char);
+ break;
+ }
+ }
+ break;
+
+ case '$':
+ if (format.size() == 1)
+ {
+ // '$' at the end of a format string, just print the '$'
+ parent_entry.AppendText("$");
+ }
+ else
+ {
+ format = format.drop_front(); // Skip the '$'
+
+ if (format[0] == '{')
+ {
+ format = format.drop_front(); // Skip the '{'
+
+ llvm::StringRef variable, variable_format;
+ error = FormatEntity::ExtractVariableInfo (format, variable, variable_format);
+ if (error.Fail())
+ return error;
+ bool verify_is_thread_id = false;
+ Entry entry;
+ if (!variable_format.empty())
+ {
+ entry.printf_format = std::move(variable_format.str());
+
+ // If the format contains a '%' we are going to assume this is
+ // a printf style format. So if you want to format your thread ID
+ // using "0x%llx" you can use:
+ // ${thread.id%0x%llx}
+ //
+ // If there is no '%' in the format, then it is assumed to be a
+ // LLDB format name, or one of the extended formats specified in
+ // the switch statement below.
+
+ if (entry.printf_format.find('%') == std::string::npos)
+ {
+ bool clear_printf = false;
+
+ if (FormatManager::GetFormatFromCString(entry.printf_format.c_str(),
+ false,
+ entry.fmt))
+ {
+ // We have an LLDB format, so clear the printf format
+ clear_printf = true;
+ }
+ else if (entry.printf_format.size() == 1)
+ {
+ switch (entry.printf_format[0])
+ {
+ case '@': // if this is an @ sign, print ObjC description
+ entry.number = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
+ clear_printf = true;
+ break;
+ case 'V': // if this is a V, print the value using the default format
+ entry.number = ValueObject::eValueObjectRepresentationStyleValue;
+ clear_printf = true;
+ break;
+ case 'L': // if this is an L, print the location of the value
+ entry.number = ValueObject::eValueObjectRepresentationStyleLocation;
+ clear_printf = true;
+ break;
+ case 'S': // if this is an S, print the summary after all
+ entry.number = ValueObject::eValueObjectRepresentationStyleSummary;
+ clear_printf = true;
+ break;
+ case '#': // if this is a '#', print the number of children
+ entry.number = ValueObject::eValueObjectRepresentationStyleChildrenCount;
+ clear_printf = true;
+ break;
+ case 'T': // if this is a 'T', print the type
+ entry.number = ValueObject::eValueObjectRepresentationStyleType;
+ clear_printf = true;
+ break;
+ case 'N': // if this is a 'N', print the name
+ entry.number = ValueObject::eValueObjectRepresentationStyleName;
+ clear_printf = true;
+ break;
+ case '>': // if this is a '>', print the expression path
+ entry.number = ValueObject::eValueObjectRepresentationStyleExpressionPath;
+ clear_printf = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("invalid format: '%s'", entry.printf_format.c_str());
+ return error;
+ }
+ }
+ else if (FormatManager::GetFormatFromCString(entry.printf_format.c_str(),
+ true,
+ entry.fmt))
+ {
+ clear_printf = true;
+ }
+ else if (entry.printf_format == "tid")
+ {
+ verify_is_thread_id = true;
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("invalid format: '%s'", entry.printf_format.c_str());
+ return error;
+ }
+
+ // Our format string turned out to not be a printf style format
+ // so lets clear the string
+ if (clear_printf)
+ entry.printf_format.clear();
+ }
+ }
+
+ // Check for dereferences
+ if (variable[0] == '*')
+ {
+ entry.deref = true;
+ variable = variable.drop_front();
+ }
+
+ error = ParseEntry (variable, &g_root, entry);
+ if (error.Fail())
+ return error;
+
+ if (verify_is_thread_id)
+ {
+ if (entry.type != Entry::Type::ThreadID &&
+ entry.type != Entry::Type::ThreadProtocolID)
+ {
+ error.SetErrorString("the 'tid' format can only be used on ${thread.id} and ${thread.protocol_id}");
+ }
+ }
+
+ switch (entry.type)
+ {
+ case Entry::Type::Variable:
+ case Entry::Type::VariableSynthetic:
+ if (entry.number == 0)
+ {
+ if (entry.string.empty())
+ entry.number = ValueObject::eValueObjectRepresentationStyleValue;
+ else
+ entry.number = ValueObject::eValueObjectRepresentationStyleSummary;
+ }
+ break;
+ default:
+ // Make sure someone didn't try to dereference anything but ${var} or ${svar}
+ if (entry.deref)
+ {
+ error.SetErrorStringWithFormat("${%s} can't be dereferenced, only ${var} and ${svar} can.", variable.str().c_str());
+ return error;
+ }
+ }
+ // Check if this entry just wants to insert a constant string
+ // value into the parent_entry, if so, insert the string with
+ // AppendText, else append the entry to the parent_entry.
+ if (entry.type == Entry::Type::InsertString)
+ parent_entry.AppendText(entry.string.c_str());
+ else
+ parent_entry.AppendEntry(std::move(entry));
+ }
+ }
+ break;
+ }
+ }
+ return error;
+}
+
+
+Error
+FormatEntity::ExtractVariableInfo (llvm::StringRef &format_str, llvm::StringRef &variable_name, llvm::StringRef &variable_format)
+{
+ Error error;
+ variable_name = llvm::StringRef();
+ variable_format = llvm::StringRef();
+
+ const size_t paren_pos = format_str.find_first_of('}');
+ if (paren_pos != llvm::StringRef::npos)
+ {
+ const size_t percent_pos = format_str.find_first_of('%');
+ if (percent_pos < paren_pos)
+ {
+ if (percent_pos > 0)
+ {
+ if (percent_pos > 1)
+ variable_name = format_str.substr(0, percent_pos);
+ variable_format = format_str.substr(percent_pos + 1, paren_pos - (percent_pos + 1));
+ }
+ }
+ else
+ {
+ variable_name = format_str.substr(0, paren_pos);
+ }
+ // Strip off elements and the formatting and the trailing '}'
+ format_str = format_str.substr(paren_pos + 1);
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("missing terminating '}' character for '${%s'", format_str.str().c_str());
+ }
+ return error;
+}
+
+bool
+FormatEntity::FormatFileSpec (const FileSpec &file_spec, Stream &s, llvm::StringRef variable_name, llvm::StringRef variable_format)
+{
+ if (variable_name.empty() || variable_name.equals(".fullpath"))
+ {
+ file_spec.Dump(&s);
+ return true;
+ }
+ else if (variable_name.equals(".basename"))
+ {
+ s.PutCString(file_spec.GetFilename().AsCString(""));
+ return true;
+ }
+ else if (variable_name.equals(".dirname"))
+ {
+ s.PutCString(file_spec.GetFilename().AsCString(""));
+ return true;
+ }
+ return false;
+}
+
+static std::string
+MakeMatch (const llvm::StringRef &prefix, const char *suffix)
+{
+ std::string match(prefix.str());
+ match.append(suffix);
+ return std::move(match);
+}
+
+static void
+AddMatches (const FormatEntity::Entry::Definition *def,
+ const llvm::StringRef &prefix,
+ const llvm::StringRef &match_prefix,
+ StringList &matches)
+{
+ const size_t n = def->num_children;
+ if (n > 0)
+ {
+ for (size_t i=0; i<n; ++i)
+ {
+ std::string match = std::move(prefix.str());
+ if (match_prefix.empty())
+ matches.AppendString(MakeMatch (prefix, def->children[i].name));
+ else if (strncmp(def->children[i].name, match_prefix.data(), match_prefix.size()) == 0)
+ matches.AppendString(MakeMatch (prefix, def->children[i].name + match_prefix.size()));
+ }
+ }
+}
+size_t
+FormatEntity::AutoComplete (const char *s,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches)
+{
+ word_complete = false;
+ llvm::StringRef str(s + match_start_point);
+ matches.Clear();
+
+ const size_t dollar_pos = str.rfind('$');
+ if (dollar_pos != llvm::StringRef::npos)
+ {
+ // Hitting TAB after $ at the end of the string add a "{"
+ if (dollar_pos == str.size() - 1)
+ {
+ std::string match = std::move(str.str());
+ match.append("{");
+ matches.AppendString(std::move(match));
+ }
+ else if (str[dollar_pos + 1] == '{')
+ {
+ const size_t close_pos = str.find('}', dollar_pos + 2);
+ if (close_pos == llvm::StringRef::npos)
+ {
+ const size_t format_pos = str.find('%', dollar_pos + 2);
+ if (format_pos == llvm::StringRef::npos)
+ {
+ llvm::StringRef partial_variable (str.substr(dollar_pos + 2));
+ if (partial_variable.empty())
+ {
+ // Suggest all top level entites as we are just past "${"
+ AddMatches(&g_root, str, llvm::StringRef(), matches);
+ }
+ else
+ {
+ // We have a partially specified variable, find it
+ llvm::StringRef remainder;
+ const FormatEntity::Entry::Definition* entry_def = FindEntry (partial_variable, &g_root, remainder);
+ if (entry_def)
+ {
+ const size_t n = entry_def->num_children;
+
+ if (remainder.empty())
+ {
+ // Exact match
+ if (n > 0)
+ {
+ // "${thread.info" <TAB>
+ matches.AppendString(std::move(MakeMatch (str, ".")));
+ }
+ else
+ {
+ // "${thread.id" <TAB>
+ matches.AppendString(std::move(MakeMatch (str, "}")));
+ word_complete = true;
+ }
+ }
+ else if (remainder.equals("."))
+ {
+ // "${thread." <TAB>
+ AddMatches(entry_def, str, llvm::StringRef(), matches);
+ }
+ else
+ {
+ // We have a partial match
+ // "${thre" <TAB>
+ AddMatches(entry_def, str, remainder, matches);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return matches.GetSize();
+}
diff --git a/source/Core/IOHandler.cpp b/source/Core/IOHandler.cpp
index 21ba965ba212..747fd4411d4d 100644
--- a/source/Core/IOHandler.cpp
+++ b/source/Core/IOHandler.cpp
@@ -3217,6 +3217,8 @@ public:
FrameTreeDelegate () :
TreeDelegate()
{
+ FormatEntity::Parse ("frame #${frame.index}: {${function.name}${function.pc-offset}}}",
+ m_format);
}
virtual ~FrameTreeDelegate()
@@ -3236,9 +3238,7 @@ public:
StreamString strm;
const SymbolContext &sc = frame_sp->GetSymbolContext(eSymbolContextEverything);
ExecutionContext exe_ctx (frame_sp);
- //const char *frame_format = "frame #${frame.index}: ${module.file.basename}{`${function.name}${function.pc-offset}}}";
- const char *frame_format = "frame #${frame.index}: {${function.name}${function.pc-offset}}}";
- if (Debugger::FormatPrompt (frame_format, &sc, &exe_ctx, NULL, strm))
+ if (FormatEntity::Format(m_format, strm, &sc, &exe_ctx, NULL, NULL, false, false))
{
int right_pad = 1;
window.PutCStringTruncated(strm.GetString().c_str(), right_pad);
@@ -3265,6 +3265,8 @@ public:
}
return false;
}
+protected:
+ FormatEntity::Entry m_format;
};
class ThreadTreeDelegate : public TreeDelegate
@@ -3276,6 +3278,8 @@ public:
m_tid (LLDB_INVALID_THREAD_ID),
m_stop_id (UINT32_MAX)
{
+ FormatEntity::Parse ("thread #${thread.index}: tid = ${thread.id}{, stop reason = ${thread.stop-reason}}",
+ m_format);
}
virtual
@@ -3306,8 +3310,7 @@ public:
{
StreamString strm;
ExecutionContext exe_ctx (thread_sp);
- const char *format = "thread #${thread.index}: tid = ${thread.id}{, stop reason = ${thread.stop-reason}}";
- if (Debugger::FormatPrompt (format, NULL, &exe_ctx, NULL, strm))
+ if (FormatEntity::Format (m_format, strm, NULL, &exe_ctx, NULL, NULL, false, false))
{
int right_pad = 1;
window.PutCStringTruncated(strm.GetString().c_str(), right_pad);
@@ -3383,6 +3386,8 @@ protected:
std::shared_ptr<FrameTreeDelegate> m_frame_delegate_sp;
lldb::user_id_t m_tid;
uint32_t m_stop_id;
+ FormatEntity::Entry m_format;
+
};
class ThreadsTreeDelegate : public TreeDelegate
@@ -3394,6 +3399,8 @@ public:
m_debugger (debugger),
m_stop_id (UINT32_MAX)
{
+ FormatEntity::Parse("process ${process.id}{, name = ${process.name}}",
+ m_format);
}
virtual
@@ -3415,8 +3422,7 @@ public:
{
StreamString strm;
ExecutionContext exe_ctx (process_sp);
- const char *format = "process ${process.id}{, name = ${process.name}}";
- if (Debugger::FormatPrompt (format, NULL, &exe_ctx, NULL, strm))
+ if (FormatEntity::Format (m_format, strm, NULL, &exe_ctx, NULL, NULL, false, false))
{
int right_pad = 1;
window.PutCStringTruncated(strm.GetString().c_str(), right_pad);
@@ -3472,6 +3478,8 @@ protected:
std::shared_ptr<ThreadTreeDelegate> m_thread_delegate_sp;
Debugger &m_debugger;
uint32_t m_stop_id;
+ FormatEntity::Entry m_format;
+
};
class ValueObjectListDelegate : public WindowDelegate
@@ -4635,6 +4643,8 @@ public:
StatusBarWindowDelegate (Debugger &debugger) :
m_debugger (debugger)
{
+ FormatEntity::Parse("Thread: ${thread.id%tid}",
+ m_format);
}
virtual
@@ -4659,8 +4669,7 @@ public:
if (StateIsStoppedState(state, true))
{
StreamString strm;
- const char *format = "Thread: ${thread.id%tid}";
- if (thread && Debugger::FormatPrompt (format, NULL, &exe_ctx, NULL, strm))
+ if (thread && FormatEntity::Format (m_format, strm, NULL, &exe_ctx, NULL, NULL, false, false))
{
window.MoveCursor (40, 0);
window.PutCStringTruncated(strm.GetString().c_str(), 1);
@@ -4686,6 +4695,7 @@ public:
protected:
Debugger &m_debugger;
+ FormatEntity::Entry m_format;
};
class SourceFileWindowDelegate : public WindowDelegate
diff --git a/source/Core/Log.cpp b/source/Core/Log.cpp
index d205d363b764..fe4cfb366c88 100644
--- a/source/Core/Log.cpp
+++ b/source/Core/Log.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
// C Includes
#include <stdio.h>
#include <stdarg.h>
@@ -20,7 +18,6 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
@@ -219,7 +216,6 @@ Log::LogIf (uint32_t bits, const char *format, ...)
}
}
-
//----------------------------------------------------------------------
// Printing of errors that are not fatal.
//----------------------------------------------------------------------
diff --git a/source/Core/Mangled.cpp b/source/Core/Mangled.cpp
index c0ab66cd2880..e1598d30e4e5 100644
--- a/source/Core/Mangled.cpp
+++ b/source/Core/Mangled.cpp
@@ -10,8 +10,9 @@
// FreeBSD9-STABLE requires this to know about size_t in cxxabi.h
#include <cstddef>
-#if defined(_MSC_VER)
-// Cannot enable the builtin demangler on msvc as it does not support the cpp11 within the implementation.
+#if defined(_MSC_VER)
+#include "lldb/Host/windows/windows.h"
+#include <Dbghelp.h>
#elif defined (__FreeBSD__)
#define LLDB_USE_BUILTIN_DEMANGLER
#else
@@ -4998,7 +4999,11 @@ static inline bool
cstring_is_mangled (const char *s)
{
if (s)
- return s[0] == '_' && s[1] == 'Z';
+#if defined(_MSC_VER)
+ return (s[0] == '?');
+#else
+ return (s[0] == '_' && s[1] == 'Z');
+#endif
return false;
}
@@ -5226,15 +5231,27 @@ Mangled::GetDemangledName () const
if (!demangled_name)
demangled_name = __cxa_demangle (mangled_cstr, NULL, NULL, NULL);
#elif defined(_MSC_VER)
- // Cannot demangle on msvc.
- char *demangled_name = nullptr;
+ char *demangled_name = (char *)::malloc(1024);
+ ::ZeroMemory(demangled_name, 1024);
+ DWORD result = ::UnDecorateSymbolName(mangled_cstr, demangled_name, 1023,
+ UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected keywords
+ UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall, etc keywords
+ UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications
+ UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc specifiers
+ UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords
+ );
+ if (result == 0)
+ {
+ free (demangled_name);
+ demangled_name = nullptr;
+ }
#else
char *demangled_name = abi::__cxa_demangle (mangled_cstr, NULL, NULL, NULL);
#endif
if (demangled_name)
{
- m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);
+ m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);
free (demangled_name);
}
}
@@ -5335,6 +5352,21 @@ Mangled::MemorySize () const
return m_mangled.MemorySize() + m_demangled.MemorySize();
}
+lldb::LanguageType
+Mangled::GetLanguage ()
+{
+ ConstString mangled = GetMangledName();
+ if (mangled)
+ {
+ if (GetDemangledName())
+ {
+ if (cstring_is_mangled(mangled.GetCString()))
+ return lldb::eLanguageTypeC_plus_plus;
+ }
+ }
+ return lldb::eLanguageTypeUnknown;
+}
+
//----------------------------------------------------------------------
// Dump OBJ to the supplied stream S.
//----------------------------------------------------------------------
diff --git a/source/Core/Module.cpp b/source/Core/Module.cpp
index 900eea2e0419..891bd87a20d4 100644
--- a/source/Core/Module.cpp
+++ b/source/Core/Module.cpp
@@ -152,7 +152,6 @@ Module::Module (const ModuleSpec &module_spec) :
m_did_load_symbol_vendor (false),
m_did_parse_uuid (false),
m_did_init_ast (false),
- m_is_dynamic_loader_module (false),
m_file_has_changed (false),
m_first_file_changed_log (false)
{
@@ -257,7 +256,6 @@ Module::Module(const FileSpec& file_spec,
m_did_load_symbol_vendor (false),
m_did_parse_uuid (false),
m_did_init_ast (false),
- m_is_dynamic_loader_module (false),
m_file_has_changed (false),
m_first_file_changed_log (false)
{
@@ -304,7 +302,6 @@ Module::Module () :
m_did_load_symbol_vendor (false),
m_did_parse_uuid (false),
m_did_init_ast (false),
- m_is_dynamic_loader_module (false),
m_file_has_changed (false),
m_first_file_changed_log (false)
{
@@ -1304,10 +1301,14 @@ Module::GetObjectFile()
data_offset);
if (m_objfile_sp)
{
- // Once we get the object file, update our module with the object file's
+ // Once we get the object file, update our module with the object file's
// architecture since it might differ in vendor/os if some parts were
- // unknown.
- m_objfile_sp->GetArchitecture (m_arch);
+ // unknown. But since the matching arch might already be more specific
+ // than the generic COFF architecture, only merge in those values that
+ // overwrite unspecified unknown values.
+ ArchSpec new_arch;
+ m_objfile_sp->GetArchitecture(new_arch);
+ m_arch.MergeFrom(new_arch);
}
else
{
@@ -1732,7 +1733,7 @@ Module::PrepareForFunctionNameLookup (const ConstString &name,
if (CPPLanguageRuntime::ExtractContextAndIdentifier (name_cstr, context, basename))
lookup_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
else
- lookup_name_type_mask = eFunctionNameTypeFull;
+ lookup_name_type_mask |= eFunctionNameTypeFull;
}
else
{
@@ -1821,3 +1822,13 @@ Module::CreateJITModule (const lldb::ObjectFileJITDelegateSP &delegate_sp)
return ModuleSP();
}
+bool
+Module::GetIsDynamicLinkEditor()
+{
+ ObjectFile * obj_file = GetObjectFile ();
+
+ if (obj_file)
+ return obj_file->GetIsDynamicLinkEditor();
+
+ return false;
+}
diff --git a/source/Core/RegisterValue.cpp b/source/Core/RegisterValue.cpp
index 91f5bea805c6..272c1eecf920 100644
--- a/source/Core/RegisterValue.cpp
+++ b/source/Core/RegisterValue.cpp
@@ -19,6 +19,7 @@
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Interpreter/Args.h"
+#include "lldb/Host/StringConvert.h"
using namespace lldb;
using namespace lldb_private;
@@ -467,7 +468,7 @@ RegisterValue::SetValueFromCString (const RegisterInfo *reg_info, const char *va
case eEncodingUint:
if (byte_size <= sizeof (uint64_t))
{
- uint64_t uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success);
+ uint64_t uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 0, &success);
if (!success)
error.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string value", value_str);
else if (!Args::UInt64ValueIsValidForByteSize (uval64, byte_size))
@@ -488,7 +489,7 @@ RegisterValue::SetValueFromCString (const RegisterInfo *reg_info, const char *va
case eEncodingSint:
if (byte_size <= sizeof (long long))
{
- uint64_t sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success);
+ uint64_t sval64 = StringConvert::ToSInt64(value_str, INT64_MAX, 0, &success);
if (!success)
error.SetErrorStringWithFormat ("'%s' is not a valid signed integer string value", value_str);
else if (!Args::SInt64ValueIsValidForByteSize (sval64, byte_size))
diff --git a/source/Core/RegularExpression.cpp b/source/Core/RegularExpression.cpp
index 54924d069537..3f712e1b2daa 100644
--- a/source/Core/RegularExpression.cpp
+++ b/source/Core/RegularExpression.cpp
@@ -7,36 +7,34 @@
//
//===----------------------------------------------------------------------===//
+#include <string.h>
#include "lldb/Core/RegularExpression.h"
#include "llvm/ADT/StringRef.h"
-#include <string.h>
+#include "lldb/Core/Error.h"
-using namespace lldb_private;
//----------------------------------------------------------------------
-// Default constructor
+// Enable enhanced mode if it is available. This allows for things like
+// \d for digit, \s for space, and many more, but it isn't available
+// everywhere.
//----------------------------------------------------------------------
-RegularExpression::RegularExpression() :
- m_re(),
- m_comp_err (1),
- m_preg(),
- m_compile_flags(REG_EXTENDED)
-{
- memset(&m_preg,0,sizeof(m_preg));
-}
+#if defined(REG_ENHANCED)
+#define DEFAULT_COMPILE_FLAGS (REG_ENHANCED|REG_EXTENDED)
+#else
+#define DEFAULT_COMPILE_FLAGS (REG_EXTENDED)
+#endif
+
+using namespace lldb_private;
//----------------------------------------------------------------------
-// Constructor that compiles "re" using "flags" and stores the
-// resulting compiled regular expression into this object.
+// Default constructor
//----------------------------------------------------------------------
-RegularExpression::RegularExpression(const char* re, int flags) :
+RegularExpression::RegularExpression() :
m_re(),
m_comp_err (1),
- m_preg(),
- m_compile_flags(flags)
+ m_preg()
{
memset(&m_preg,0,sizeof(m_preg));
- Compile(re);
}
//----------------------------------------------------------------------
@@ -46,8 +44,7 @@ RegularExpression::RegularExpression(const char* re, int flags) :
RegularExpression::RegularExpression(const char* re) :
m_re(),
m_comp_err (1),
- m_preg(),
- m_compile_flags(REG_EXTENDED)
+ m_preg()
{
memset(&m_preg,0,sizeof(m_preg));
Compile(re);
@@ -56,16 +53,14 @@ RegularExpression::RegularExpression(const char* re) :
RegularExpression::RegularExpression(const RegularExpression &rhs)
{
memset(&m_preg,0,sizeof(m_preg));
- Compile(rhs.GetText(), rhs.GetCompileFlags());
+ Compile(rhs.GetText());
}
const RegularExpression &
RegularExpression::operator= (const RegularExpression &rhs)
{
if (&rhs != this)
- {
- Compile (rhs.GetText(), rhs.GetCompileFlags());
- }
+ Compile (rhs.GetText());
return *this;
}
//----------------------------------------------------------------------
@@ -94,19 +89,12 @@ RegularExpression::~RegularExpression()
bool
RegularExpression::Compile(const char* re)
{
- return Compile (re, m_compile_flags);
-}
-
-bool
-RegularExpression::Compile(const char* re, int flags)
-{
Free();
- m_compile_flags = flags;
if (re && re[0])
{
m_re = re;
- m_comp_err = ::regcomp (&m_preg, re, flags);
+ m_comp_err = ::regcomp (&m_preg, re, DEFAULT_COMPILE_FLAGS);
}
else
{
@@ -126,7 +114,7 @@ RegularExpression::Compile(const char* re, int flags)
// will be executed using the "execute_flags".
//---------------------------------------------------------------------
bool
-RegularExpression::Execute(const char* s, Match *match, int execute_flags) const
+RegularExpression::Execute (const char* s, Match *match) const
{
int err = 1;
if (s != NULL && m_comp_err == 0)
@@ -137,7 +125,7 @@ RegularExpression::Execute(const char* s, Match *match, int execute_flags) const
s,
match->GetSize(),
match->GetData(),
- execute_flags);
+ 0);
}
else
{
@@ -145,7 +133,7 @@ RegularExpression::Execute(const char* s, Match *match, int execute_flags) const
s,
0,
NULL,
- execute_flags);
+ 0);
}
}
diff --git a/source/Core/Scalar.cpp b/source/Core/Scalar.cpp
index 1bfe6f2f1baf..0e9b98dc4ab6 100644
--- a/source/Core/Scalar.cpp
+++ b/source/Core/Scalar.cpp
@@ -17,6 +17,7 @@
#include "lldb/Core/Stream.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Host/Endian.h"
+#include "lldb/Host/StringConvert.h"
#include "Plugins/Process/Utility/InstructionUtils.h"
@@ -1790,7 +1791,7 @@ Scalar::SetValueFromCString (const char *value_str, Encoding encoding, size_t by
case eEncodingUint:
if (byte_size <= sizeof (unsigned long long))
{
- uint64_t uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success);
+ uint64_t uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 0, &success);
if (!success)
error.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string value", value_str);
else if (!UIntValueIsValidForSize (uval64, byte_size))
@@ -1819,7 +1820,7 @@ Scalar::SetValueFromCString (const char *value_str, Encoding encoding, size_t by
case eEncodingSint:
if (byte_size <= sizeof (long long))
{
- uint64_t sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success);
+ uint64_t sval64 = StringConvert::ToSInt64(value_str, INT64_MAX, 0, &success);
if (!success)
error.SetErrorStringWithFormat ("'%s' is not a valid signed integer string value", value_str);
else if (!SIntValueIsValidForSize (sval64, byte_size))
diff --git a/source/Core/StreamFile.cpp b/source/Core/StreamFile.cpp
index 2285ca954457..9f8dd629e3d4 100644
--- a/source/Core/StreamFile.cpp
+++ b/source/Core/StreamFile.cpp
@@ -49,7 +49,8 @@ StreamFile::StreamFile (FILE *fh, bool transfer_ownership) :
StreamFile::StreamFile (const char *path) :
Stream (),
- m_file (path, File::eOpenOptionWrite | File::eOpenOptionCanCreate, lldb::eFilePermissionsFileDefault)
+ m_file (path, File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionCloseOnExec,
+ lldb::eFilePermissionsFileDefault)
{
}
diff --git a/source/Core/Value.cpp b/source/Core/Value.cpp
index db33fce4a03e..a416d0745a69 100644
--- a/source/Core/Value.cpp
+++ b/source/Core/Value.cpp
@@ -277,7 +277,7 @@ Value::GetValueByteSize (Error *error_ptr)
{
const ClangASTType &ast_type = GetClangType();
if (ast_type.IsValid())
- byte_size = ast_type.GetByteSize();
+ byte_size = ast_type.GetByteSize(nullptr);
}
break;
}
@@ -434,7 +434,7 @@ Value::GetValueAsData (ExecutionContext *exe_ctx,
lldb::Encoding type_encoding = ast_type.GetEncoding(type_encoding_count);
if (type_encoding == eEncodingUint || type_encoding == eEncodingSint)
- limit_byte_size = ast_type.GetByteSize();
+ limit_byte_size = ast_type.GetByteSize(nullptr);
}
if (m_value.GetData (data, limit_byte_size))
diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp
index fa5fb14db05b..b72e5c3f18c6 100644
--- a/source/Core/ValueObject.cpp
+++ b/source/Core/ValueObject.cpp
@@ -99,6 +99,7 @@ ValueObject::ValueObject (ValueObject &parent) :
m_user_id_of_forced_summary(),
m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid),
m_value_checksum(),
+ m_preferred_display_language(lldb::eLanguageTypeUnknown),
m_value_is_valid (false),
m_value_did_change (false),
m_children_count_valid (false),
@@ -149,6 +150,7 @@ ValueObject::ValueObject (ExecutionContextScope *exe_scope,
m_user_id_of_forced_summary(),
m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type),
m_value_checksum(),
+ m_preferred_display_language(lldb::eLanguageTypeUnknown),
m_value_is_valid (false),
m_value_did_change (false),
m_children_count_valid (false),
@@ -969,7 +971,9 @@ ValueObject::GetPointeeData (DataExtractor& data,
if (item_count == 0)
return 0;
- const uint64_t item_type_size = pointee_or_element_clang_type.GetByteSize();
+ ExecutionContext exe_ctx (GetExecutionContextRef());
+
+ const uint64_t item_type_size = pointee_or_element_clang_type.GetByteSize(&exe_ctx);
const uint64_t bytes = item_count * item_type_size;
const uint64_t offset = item_idx * item_type_size;
@@ -1045,7 +1049,7 @@ ValueObject::GetPointeeData (DataExtractor& data,
break;
case eAddressTypeHost:
{
- const uint64_t max_bytes = GetClangType().GetByteSize();
+ const uint64_t max_bytes = GetClangType().GetByteSize(&exe_ctx);
if (max_bytes > offset)
{
size_t bytes_read = std::min<uint64_t>(max_bytes - offset, bytes);
@@ -1505,14 +1509,14 @@ ValueObject::GetValueAsSigned (int64_t fail_value, bool *success)
{
if (success)
*success = true;
- return scalar.SLongLong(fail_value);
+ return scalar.SLongLong(fail_value);
}
// fallthrough, otherwise...
}
if (success)
*success = false;
- return fail_value;
+ return fail_value;
}
// if any more "special cases" are added to ValueObject::DumpPrintableRepresentation() please keep
@@ -2220,10 +2224,12 @@ ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type
if (!can_create)
return ValueObjectSP();
+ ExecutionContext exe_ctx (GetExecutionContextRef());
+
ValueObjectChild *synthetic_child = new ValueObjectChild(*this,
type,
name_const_str,
- type.GetByteSize(),
+ type.GetByteSize(&exe_ctx),
offset,
0,
0,
@@ -2261,10 +2267,12 @@ ValueObject::GetSyntheticBase (uint32_t offset, const ClangASTType& type, bool c
const bool is_base_class = true;
+ ExecutionContext exe_ctx (GetExecutionContextRef());
+
ValueObjectChild *synthetic_child = new ValueObjectChild(*this,
type,
name_const_str,
- type.GetByteSize(),
+ type.GetByteSize(&exe_ctx),
offset,
0,
0,
@@ -4128,16 +4136,22 @@ ValueObject::GetRoot ()
{
if (m_root)
return m_root;
- ValueObject* parent = m_parent;
- if (!parent)
- return (m_root = this);
- while (parent->m_parent)
+ return (m_root = FollowParentChain( [] (ValueObject* vo) -> bool {
+ return (vo->m_parent != nullptr);
+ }));
+}
+
+ValueObject*
+ValueObject::FollowParentChain (std::function<bool(ValueObject*)> f)
+{
+ ValueObject* vo = this;
+ while (vo)
{
- if (parent->m_root)
- return (m_root = parent->m_root);
- parent = parent->m_parent;
+ if (f(vo) == false)
+ break;
+ vo = vo->m_parent;
}
- return (m_root = parent);
+ return vo;
}
AddressType
@@ -4181,24 +4195,33 @@ ValueObject::GetFormat () const
lldb::LanguageType
ValueObject::GetPreferredDisplayLanguage ()
{
- lldb::LanguageType type = lldb::eLanguageTypeUnknown;
- if (GetRoot())
+ lldb::LanguageType type = m_preferred_display_language;
+ if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
{
- if (GetRoot() == this)
+ if (GetRoot())
{
- if (StackFrameSP frame_sp = GetFrameSP())
+ if (GetRoot() == this)
{
- const SymbolContext& sc(frame_sp->GetSymbolContext(eSymbolContextCompUnit));
- if (CompileUnit* cu = sc.comp_unit)
- type = cu->GetLanguage();
+ if (StackFrameSP frame_sp = GetFrameSP())
+ {
+ const SymbolContext& sc(frame_sp->GetSymbolContext(eSymbolContextCompUnit));
+ if (CompileUnit* cu = sc.comp_unit)
+ type = cu->GetLanguage();
+ }
+ }
+ else
+ {
+ type = GetRoot()->GetPreferredDisplayLanguage();
}
- }
- else
- {
- type = GetRoot()->GetPreferredDisplayLanguage();
}
}
- return type;
+ return (m_preferred_display_language = type); // only compute it once
+}
+
+void
+ValueObject::SetPreferredDisplayLanguage (lldb::LanguageType lt)
+{
+ m_preferred_display_language = lt;
}
bool
diff --git a/source/Core/ValueObjectConstResult.cpp b/source/Core/ValueObjectConstResult.cpp
index fc870d726221..e8b477a74a52 100644
--- a/source/Core/ValueObjectConstResult.cpp
+++ b/source/Core/ValueObjectConstResult.cpp
@@ -256,8 +256,10 @@ ValueObjectConstResult::GetValueType() const
uint64_t
ValueObjectConstResult::GetByteSize()
{
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+
if (m_byte_size == 0)
- m_byte_size = GetClangType().GetByteSize();
+ SetByteSize(GetClangType().GetByteSize(&exe_ctx));
return m_byte_size;
}
diff --git a/source/Core/ValueObjectDynamicValue.cpp b/source/Core/ValueObjectDynamicValue.cpp
index 1b8ec8083f8f..89b98a1db1ba 100644
--- a/source/Core/ValueObjectDynamicValue.cpp
+++ b/source/Core/ValueObjectDynamicValue.cpp
@@ -127,7 +127,7 @@ ValueObjectDynamicValue::GetByteSize()
{
const bool success = UpdateValueIfNeeded(false);
if (success && m_dynamic_type_info.HasType())
- return m_value.GetValueByteSize(NULL);
+ return m_value.GetValueByteSize(nullptr);
else
return m_parent->GetByteSize();
}
diff --git a/source/Core/ValueObjectMemory.cpp b/source/Core/ValueObjectMemory.cpp
index 5fbe87b66522..9f1953138f62 100644
--- a/source/Core/ValueObjectMemory.cpp
+++ b/source/Core/ValueObjectMemory.cpp
@@ -169,7 +169,7 @@ ValueObjectMemory::GetByteSize()
{
if (m_type_sp)
return m_type_sp->GetByteSize();
- return m_clang_type.GetByteSize ();
+ return m_clang_type.GetByteSize (nullptr);
}
lldb::ValueType
diff --git a/source/Core/ValueObjectSyntheticFilter.cpp b/source/Core/ValueObjectSyntheticFilter.cpp
index dafe73a5e57e..e266267981b8 100644
--- a/source/Core/ValueObjectSyntheticFilter.cpp
+++ b/source/Core/ValueObjectSyntheticFilter.cpp
@@ -298,3 +298,9 @@ ValueObjectSynthetic::CanProvideValue ()
return true;
return m_parent->CanProvideValue();
}
+
+bool
+ValueObjectSynthetic::SetValueFromCString (const char *value_str, Error& error)
+{
+ return m_parent->SetValueFromCString(value_str, error);
+}
diff --git a/source/Core/ValueObjectVariable.cpp b/source/Core/ValueObjectVariable.cpp
index ab74a50e7cd5..ed2aeb3d9634 100644
--- a/source/Core/ValueObjectVariable.cpp
+++ b/source/Core/ValueObjectVariable.cpp
@@ -105,12 +105,14 @@ ValueObjectVariable::CalculateNumChildren()
uint64_t
ValueObjectVariable::GetByteSize()
{
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+
ClangASTType type(GetClangType());
if (!type.IsValid())
return 0;
- return type.GetByteSize();
+ return type.GetByteSize(&exe_ctx);
}
lldb::ValueType
diff --git a/source/DataFormatters/CXXFormatterFunctions.cpp b/source/DataFormatters/CXXFormatterFunctions.cpp
index 04cdadf5a98f..5aa8289794c1 100644
--- a/source/DataFormatters/CXXFormatterFunctions.cpp
+++ b/source/DataFormatters/CXXFormatterFunctions.cpp
@@ -317,7 +317,7 @@ lldb_private::formatters::WCharStringSummaryProvider (ValueObject& valobj, Strea
return false;
ClangASTType wchar_clang_type = ClangASTContext::GetBasicType(ast, lldb::eBasicTypeWChar);
- const uint32_t wchar_size = wchar_clang_type.GetBitSize();
+ const uint32_t wchar_size = wchar_clang_type.GetBitSize(nullptr);
ReadStringAndDumpToStreamOptions options(valobj);
options.SetLocation(data_addr);
diff --git a/source/DataFormatters/FormatManager.cpp b/source/DataFormatters/FormatManager.cpp
index 01799cef5e4e..ae52b3309ed8 100644
--- a/source/DataFormatters/FormatManager.cpp
+++ b/source/DataFormatters/FormatManager.cpp
@@ -251,6 +251,8 @@ FormatManager::GetPossibleMatches (ValueObject& valobj,
do
{
lldb::ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ break;
ObjCLanguageRuntime* runtime = process_sp->GetObjCLanguageRuntime();
if (runtime == nullptr)
break;
diff --git a/source/DataFormatters/LibCxx.cpp b/source/DataFormatters/LibCxx.cpp
index 26bbcf91242f..728ad84341f0 100644
--- a/source/DataFormatters/LibCxx.cpp
+++ b/source/DataFormatters/LibCxx.cpp
@@ -14,6 +14,7 @@
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Error.h"
+#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
@@ -139,7 +140,7 @@ lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetChildAtIndex (si
return ValueObjectSP();
}
bool bit_set = ((byte & mask) != 0);
- DataBufferSP buffer_sp(new DataBufferHeap(m_bool_type.GetByteSize(),0));
+ DataBufferSP buffer_sp(new DataBufferHeap(m_bool_type.GetByteSize(nullptr),0));
if (bit_set && buffer_sp && buffer_sp->GetBytes())
*(buffer_sp->GetBytes()) = 1; // regardless of endianness, anything non-zero is true
StreamString name; name.Printf("[%" PRIu64 "]", (uint64_t)idx);
@@ -460,5 +461,5 @@ lldb_private::formatters::LibcxxContainerSummaryProvider (ValueObject& valobj, S
return false;
stream.Printf("0x%016" PRIx64 " ", value);
}
- return Debugger::FormatPrompt("size=${svar%#}", NULL, NULL, NULL, stream, &valobj);
+ return FormatEntity::FormatStringRef("size=${svar%#}", stream, NULL, NULL, NULL, &valobj, false, false);
}
diff --git a/source/DataFormatters/LibCxxInitializerList.cpp b/source/DataFormatters/LibCxxInitializerList.cpp
index e76b0bec95ce..91f1f90507a7 100644
--- a/source/DataFormatters/LibCxxInitializerList.cpp
+++ b/source/DataFormatters/LibCxxInitializerList.cpp
@@ -107,7 +107,7 @@ lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::Update()
if (kind != lldb::eTemplateArgumentKindType || false == m_element_type.IsValid())
return false;
- m_element_size = m_element_type.GetByteSize();
+ m_element_size = m_element_type.GetByteSize(nullptr);
if (m_element_size > 0)
m_start = m_backend.GetChildMemberWithName(g___begin_,true).get(); // store raw pointers or end up with a circular dependency
diff --git a/source/DataFormatters/LibCxxVector.cpp b/source/DataFormatters/LibCxxVector.cpp
index 26c62afbed2b..d0e6be486d65 100644
--- a/source/DataFormatters/LibCxxVector.cpp
+++ b/source/DataFormatters/LibCxxVector.cpp
@@ -115,7 +115,7 @@ lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update()
if (!data_type_finder_sp)
return false;
m_element_type = data_type_finder_sp->GetClangType().GetPointeeType();
- m_element_size = m_element_type.GetByteSize();
+ m_element_size = m_element_type.GetByteSize(nullptr);
if (m_element_size > 0)
{
diff --git a/source/DataFormatters/TypeSummary.cpp b/source/DataFormatters/TypeSummary.cpp
index ff089af58cb7..4c9cd582e642 100644
--- a/source/DataFormatters/TypeSummary.cpp
+++ b/source/DataFormatters/TypeSummary.cpp
@@ -86,13 +86,30 @@ m_flags(flags)
StringSummaryFormat::StringSummaryFormat (const TypeSummaryImpl::Flags& flags,
const char *format_cstr) :
-TypeSummaryImpl(flags),
-m_format()
+ TypeSummaryImpl(flags),
+ m_format_str()
{
- if (format_cstr)
- m_format.assign(format_cstr);
+ SetSummaryString (format_cstr);
}
+void
+StringSummaryFormat::SetSummaryString (const char* format_cstr)
+{
+ m_format.Clear();
+ if (format_cstr && format_cstr[0])
+ {
+ m_format_str = format_cstr;
+ m_error = FormatEntity::Parse(format_cstr, m_format);
+ }
+ else
+ {
+ m_format_str.clear();
+ m_error.Clear();
+ }
+}
+
+
+
bool
StringSummaryFormat::FormatObject (ValueObject *valobj,
std::string& retval,
@@ -120,7 +137,7 @@ StringSummaryFormat::FormatObject (ValueObject *valobj,
}
else
{
- if (Debugger::FormatPrompt(m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, valobj))
+ if (FormatEntity::Format(m_format, s, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), valobj, false, false))
{
retval.assign(s.GetString());
return true;
@@ -138,7 +155,10 @@ StringSummaryFormat::GetDescription ()
{
StreamString sstr;
- sstr.Printf ("`%s`%s%s%s%s%s%s%s", m_format.c_str(),
+ sstr.Printf ("`%s`%s%s%s%s%s%s%s%s%s",
+ m_format_str.c_str(),
+ m_error.Fail() ? " error: " : "",
+ m_error.Fail() ? m_error.AsCString() : "",
Cascades() ? "" : " (not cascading)",
!DoesPrintChildren(nullptr) ? "" : " (show children)",
!DoesPrintValue(nullptr) ? " (hide value)" : "",
@@ -153,8 +173,8 @@ CXXFunctionSummaryFormat::CXXFunctionSummaryFormat (const TypeSummaryImpl::Flags
Callback impl,
const char* description) :
TypeSummaryImpl(flags),
-m_impl(impl),
-m_description(description ? description : "")
+ m_impl(impl),
+ m_description(description ? description : "")
{
}
diff --git a/source/DataFormatters/TypeSynthetic.cpp b/source/DataFormatters/TypeSynthetic.cpp
index 13c1c7508b68..b150b2bb6ee3 100644
--- a/source/DataFormatters/TypeSynthetic.cpp
+++ b/source/DataFormatters/TypeSynthetic.cpp
@@ -68,18 +68,24 @@ size_t
TypeFilterImpl::FrontEnd::GetIndexOfChildWithName (const ConstString &name)
{
const char* name_cstr = name.GetCString();
- for (size_t i = 0; i < filter->GetCount(); i++)
+ if (name_cstr)
{
- const char* expr_cstr = filter->GetExpressionPathAtIndex(i);
- if (expr_cstr)
+ for (size_t i = 0; i < filter->GetCount(); i++)
{
- if (*expr_cstr == '.')
- expr_cstr++;
- else if (*expr_cstr == '-' && *(expr_cstr+1) == '>')
- expr_cstr += 2;
+ const char* expr_cstr = filter->GetExpressionPathAtIndex(i);
+ if (expr_cstr)
+ {
+ if (*expr_cstr == '.')
+ expr_cstr++;
+ else if (*expr_cstr == '-' && *(expr_cstr+1) == '>')
+ expr_cstr += 2;
+ }
+ if (expr_cstr)
+ {
+ if (!::strcmp(name_cstr, expr_cstr))
+ return i;
+ }
}
- if (!::strcmp(name_cstr, expr_cstr))
- return i;
}
return UINT32_MAX;
}
diff --git a/source/Expression/ASTResultSynthesizer.cpp b/source/Expression/ASTResultSynthesizer.cpp
index 2f14721100bc..c3d42cb49ec5 100644
--- a/source/Expression/ASTResultSynthesizer.cpp
+++ b/source/Expression/ASTResultSynthesizer.cpp
@@ -480,10 +480,10 @@ ASTResultSynthesizer::CompleteTentativeDefinition(VarDecl *D)
}
void
-ASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired)
+ASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD)
{
if (m_passthrough)
- m_passthrough->HandleVTable(RD, DefinitionRequired);
+ m_passthrough->HandleVTable(RD);
}
void
diff --git a/source/Expression/ASTStructExtractor.cpp b/source/Expression/ASTStructExtractor.cpp
index 2a8b7bc7d8ec..98628dbc92be 100644
--- a/source/Expression/ASTStructExtractor.cpp
+++ b/source/Expression/ASTStructExtractor.cpp
@@ -186,10 +186,10 @@ ASTStructExtractor::CompleteTentativeDefinition(VarDecl *D)
}
void
-ASTStructExtractor::HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired)
+ASTStructExtractor::HandleVTable(CXXRecordDecl *RD)
{
if (m_passthrough)
- m_passthrough->HandleVTable(RD, DefinitionRequired);
+ m_passthrough->HandleVTable(RD);
}
void
diff --git a/source/Expression/ClangExpressionParser.cpp b/source/Expression/ClangExpressionParser.cpp
index 4906108401af..d05d9b99df07 100644
--- a/source/Expression/ClangExpressionParser.cpp
+++ b/source/Expression/ClangExpressionParser.cpp
@@ -329,7 +329,6 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
m_code_generator.reset(CreateLLVMCodeGen(m_compiler->getDiagnostics(),
module_name,
m_compiler->getCodeGenOpts(),
- m_compiler->getTargetOpts(),
*m_llvm_context));
}
diff --git a/source/Expression/ClangModulesDeclVendor.cpp b/source/Expression/ClangModulesDeclVendor.cpp
index 46adaaff33ce..0800b52e7e99 100644
--- a/source/Expression/ClangModulesDeclVendor.cpp
+++ b/source/Expression/ClangModulesDeclVendor.cpp
@@ -7,8 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/StreamString.h"
+#include <mutex> // std::once
+
#include "lldb/Expression/ClangModulesDeclVendor.h"
+
+#include "lldb/Core/StreamString.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
@@ -22,7 +25,6 @@
#include "clang/Sema/Lookup.h"
#include "clang/Serialization/ASTReader.h"
-#include <mutex>
using namespace lldb_private;
@@ -289,7 +291,7 @@ ClangModulesDeclVendor::Create(Target &target)
"-Werror=non-modular-include-in-framework-module"
};
- target.GetPlatform()->AddClangModuleCompilationOptions(compiler_invocation_arguments);
+ target.GetPlatform()->AddClangModuleCompilationOptions(&target, compiler_invocation_arguments);
compiler_invocation_arguments.push_back(ModuleImportBufferName);
diff --git a/source/Expression/ExpressionSourceCode.cpp b/source/Expression/ExpressionSourceCode.cpp
index 080562e51e91..b3f335f1b314 100644
--- a/source/Expression/ExpressionSourceCode.cpp
+++ b/source/Expression/ExpressionSourceCode.cpp
@@ -41,13 +41,17 @@ typedef __UINTPTR_TYPE__ uintptr_t;
typedef __SIZE_TYPE__ size_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef unsigned short unichar;
+extern "C"
+{
+ int printf(const char * __restrict, ...);
+}
)";
bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrapping_language, bool const_object, bool static_method, ExecutionContext &exe_ctx) const
{
const char *target_specific_defines = "typedef signed char BOOL;\n";
- static ConstString g_platform_ios_simulator ("PlatformiOSSimulator");
+ static ConstString g_platform_ios_simulator ("ios-simulator");
if (Target *target = exe_ctx.GetTargetPtr())
{
diff --git a/source/Expression/IRExecutionUnit.cpp b/source/Expression/IRExecutionUnit.cpp
index e7cb728778e6..9ca9e25907b6 100644
--- a/source/Expression/IRExecutionUnit.cpp
+++ b/source/Expression/IRExecutionUnit.cpp
@@ -199,28 +199,8 @@ IRExecutionUnit::DisassembleFunction (Stream &stream,
disassembler_sp->DecodeInstructions (Address (func_remote_addr), extractor, 0, UINT32_MAX, false, false);
InstructionList &instruction_list = disassembler_sp->GetInstructionList();
- const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
- const char *disassemble_format = "${addr-file-or-load}: ";
- if (exe_ctx.HasTargetScope())
- {
- disassemble_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat();
- }
-
- for (size_t instruction_index = 0, num_instructions = instruction_list.GetSize();
- instruction_index < num_instructions;
- ++instruction_index)
- {
- Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index).get();
- instruction->Dump (&stream,
- max_opcode_byte_size,
- true,
- true,
- &exe_ctx,
- NULL,
- NULL,
- disassemble_format);
- stream.PutChar('\n');
- }
+ instruction_list.Dump(&stream, true, true, &exe_ctx);
+
// FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
// I'll fix that but for now, just clear the list and it will go away nicely.
disassembler_sp->GetInstructionList().Clear();
@@ -239,6 +219,12 @@ static void ReportInlineAsmError(const llvm::SMDiagnostic &diagnostic, void *Con
}
void
+IRExecutionUnit::ReportSymbolLookupError(const ConstString &name)
+{
+ m_failed_lookups.push_back(name);
+}
+
+void
IRExecutionUnit::GetRunnableInfo(Error &error,
lldb::addr_t &func_addr,
lldb::addr_t &func_end)
@@ -369,6 +355,33 @@ IRExecutionUnit::GetRunnableInfo(Error &error,
ReportAllocations(*m_execution_engine_ap);
WriteData(process_sp);
+ if (m_failed_lookups.size())
+ {
+ StreamString ss;
+
+ ss.PutCString("Couldn't lookup symbols:\n");
+
+ bool emitNewLine = false;
+
+ for (const ConstString &failed_lookup : m_failed_lookups)
+ {
+ if (emitNewLine)
+ ss.PutCString("\n");
+ emitNewLine = true;
+ ss.PutCString(" ");
+ ss.PutCString(Mangled(failed_lookup).GetDemangledName().AsCString());
+ }
+
+ m_failed_lookups.clear();
+
+ error.SetErrorString(ss.GetData());
+
+ return;
+ }
+
+ m_function_load_addr = LLDB_INVALID_ADDRESS;
+ m_function_end_load_addr = LLDB_INVALID_ADDRESS;
+
for (JittedFunction &jitted_function : m_jitted_functions)
{
jitted_function.m_remote_addr = GetRemoteAddressForLocal (jitted_function.m_local_addr);
@@ -604,6 +617,114 @@ IRExecutionUnit::MemoryManager::allocateDataSection(uintptr_t Size,
return return_value;
}
+uint64_t
+IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+ SymbolContextList sc_list;
+
+ ExecutionContextScope *exe_scope = m_parent.GetBestExecutionContextScope();
+
+ lldb::TargetSP target_sp = exe_scope->CalculateTarget();
+
+ const char *name = Name.c_str();
+
+ ConstString bare_name_cs(name);
+ ConstString name_cs;
+
+ if (name[0] == '_')
+ name_cs = ConstString(name + 1);
+
+ if (!target_sp)
+ {
+ if (log)
+ log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <no target>",
+ Name.c_str());
+
+ m_parent.ReportSymbolLookupError(name_cs);
+
+ return 0xbad0bad0;
+ }
+
+ uint32_t num_matches = 0;
+ lldb::ProcessSP process_sp = exe_scope->CalculateProcess();
+
+ if (!name_cs.IsEmpty())
+ {
+ target_sp->GetImages().FindSymbolsWithNameAndType(name_cs, lldb::eSymbolTypeAny, sc_list);
+ num_matches = sc_list.GetSize();
+ }
+
+ if (!num_matches)
+ {
+ target_sp->GetImages().FindSymbolsWithNameAndType(bare_name_cs, lldb::eSymbolTypeAny, sc_list);
+ num_matches = sc_list.GetSize();
+ }
+
+ lldb::addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
+
+ for (uint32_t i=0; i<num_matches && (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS); i++)
+ {
+ SymbolContext sym_ctx;
+ sc_list.GetContextAtIndex(i, sym_ctx);
+
+ if (sym_ctx.symbol->GetType() == lldb::eSymbolTypeUndefined)
+ continue;
+
+ const Address *sym_address = &sym_ctx.symbol->GetAddress();
+
+ if (!sym_address || !sym_address->IsValid())
+ continue;
+
+ symbol_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target_sp);
+
+ if (symbol_load_addr == LLDB_INVALID_ADDRESS)
+ {
+ symbol_load_addr = sym_ctx.symbol->GetAddress().GetLoadAddress(target_sp.get());
+ }
+ }
+
+ if (symbol_load_addr == LLDB_INVALID_ADDRESS && process_sp && name_cs)
+ {
+ // Try the Objective-C language runtime.
+
+ ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime();
+
+ if (runtime)
+ symbol_load_addr = runtime->LookupRuntimeSymbol(name_cs);
+ }
+
+ if (symbol_load_addr == LLDB_INVALID_ADDRESS)
+ {
+ if (log)
+ log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <not found>",
+ name);
+
+ m_parent.ReportSymbolLookupError(bare_name_cs);
+
+ return 0xbad0bad0;
+ }
+
+ if (log)
+ log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = %" PRIx64,
+ name,
+ symbol_load_addr);
+
+ if (symbol_load_addr == 0)
+ return 0xbad00add;
+
+ return symbol_load_addr;
+}
+
+void *
+IRExecutionUnit::MemoryManager::getPointerToNamedFunction(const std::string &Name,
+ bool AbortOnFailure) {
+ assert (sizeof(void *) == 8);
+
+ return (void*)getSymbolAddress(Name);
+}
+
lldb::addr_t
IRExecutionUnit::GetRemoteAddressForLocal (lldb::addr_t local_address)
{
diff --git a/source/Expression/IRForTarget.cpp b/source/Expression/IRForTarget.cpp
index 8e75c32183ec..42390b35fdde 100644
--- a/source/Expression/IRForTarget.cpp
+++ b/source/Expression/IRForTarget.cpp
@@ -590,7 +590,7 @@ IRForTarget::CreateResultVariable (llvm::Function &llvm_function)
&result_decl->getASTContext());
}
- if (m_result_type.GetBitSize() == 0)
+ if (m_result_type.GetBitSize(nullptr) == 0)
{
lldb_private::StreamString type_desc_stream;
m_result_type.DumpTypeDescription(&type_desc_stream);
@@ -617,7 +617,7 @@ IRForTarget::CreateResultVariable (llvm::Function &llvm_function)
if (log)
log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
m_result_name.GetCString(),
- m_result_type.GetByteSize());
+ m_result_type.GetByteSize(nullptr));
// Construct a new result global and set up its metadata
@@ -1518,7 +1518,7 @@ IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr)
value_type = global_variable->getType();
}
- const uint64_t value_size = clang_type.GetByteSize();
+ const uint64_t value_size = clang_type.GetByteSize(nullptr);
lldb::offset_t value_alignment = (clang_type.GetTypeBitAlign() + 7ull) / 8ull;
if (log)
diff --git a/source/Expression/Materializer.cpp b/source/Expression/Materializer.cpp
index b11921635e5a..f1f2f99eed5e 100644
--- a/source/Expression/Materializer.cpp
+++ b/source/Expression/Materializer.cpp
@@ -49,7 +49,7 @@ Materializer::AddStructMember (Entity &entity)
void
Materializer::Entity::SetSizeAndAlignmentFromType (ClangASTType &type)
{
- m_size = type.GetByteSize();
+ m_size = type.GetByteSize(nullptr);
uint32_t bit_alignment = type.GetTypeBitAlign();
@@ -780,7 +780,7 @@ public:
const lldb::addr_t load_addr = process_address + m_offset;
- size_t byte_size = m_type.GetByteSize();
+ size_t byte_size = m_type.GetByteSize(nullptr);
size_t bit_align = m_type.GetTypeBitAlign();
size_t byte_align = (bit_align + 7) / 8;
diff --git a/source/Host/common/Editline.cpp b/source/Host/common/Editline.cpp
index b82fbea90c6c..a127d58b2767 100644
--- a/source/Host/common/Editline.cpp
+++ b/source/Host/common/Editline.cpp
@@ -24,6 +24,20 @@
using namespace lldb_private;
using namespace lldb_private::line_editor;
+// Workaround for what looks like an OS X-specific issue, but other platforms
+// may benefit from something similar if issues arise. The libedit library
+// doesn't explicitly initialize the curses termcap library, which it gets away
+// with until TERM is set to VT100 where it stumbles over an implementation
+// assumption that may not exist on other platforms. The setupterm() function
+// would normally require headers that don't work gracefully in this context, so
+// the function declaraction has been hoisted here.
+#if defined(__APPLE__)
+extern "C" {
+ int setupterm(char *term, int fildes, int *errret);
+}
+#define USE_SETUPTERM_WORKAROUND
+#endif
+
// Editline uses careful cursor management to achieve the illusion of editing a multi-line block of text
// with a single line editor. Preserving this illusion requires fairly careful management of cursor
// state. Read and understand the relationship between DisplayInput(), MoveCursor(), SetCurrentLine(),
@@ -1313,6 +1327,10 @@ Editline::GetLine (std::string &line, bool &interrupted)
m_editor_getting_char = false;
m_revert_cursor_index = -1;
+#ifdef USE_SETUPTERM_WORKAROUND
+ setupterm((char *)0, fileno(m_output_file), (int *)0);
+#endif
+
int count;
auto input = el_wgets (m_editline, &count);
@@ -1359,6 +1377,9 @@ Editline::GetLines (int first_line_number, StringList &lines, bool &interrupted)
m_revert_cursor_index = -1;
while (m_editor_status == EditorStatus::Editing)
{
+#ifdef USE_SETUPTERM_WORKAROUND
+ setupterm((char *)0, fileno(m_output_file), (int *)0);
+#endif
int count;
m_current_line_rows = -1;
el_wpush (m_editline, EditLineConstString("\x1b[^")); // Revert to the existing line content
diff --git a/source/Host/common/File.cpp b/source/Host/common/File.cpp
index c3c77835ce86..946f3dd6fef5 100644
--- a/source/Host/common/File.cpp
+++ b/source/Host/common/File.cpp
@@ -288,6 +288,8 @@ File::Open (const char *path, uint32_t options, uint32_t permissions)
#ifndef _WIN32
if (options & eOpenOptionNonBlocking)
oflag |= O_NONBLOCK;
+ if (options & eOpenOptionCloseOnExec)
+ oflag |= O_CLOEXEC;
#else
oflag |= O_BINARY;
#endif
@@ -742,8 +744,9 @@ File::Read (size_t &num_bytes, off_t &offset, bool null_terminate, DataBufferSP
if (num_bytes > bytes_left)
num_bytes = bytes_left;
+ size_t num_bytes_plus_nul_char = num_bytes + (null_terminate ? 1 : 0);
std::unique_ptr<DataBufferHeap> data_heap_ap;
- data_heap_ap.reset(new DataBufferHeap(num_bytes + (null_terminate ? 1 : 0), '\0'));
+ data_heap_ap.reset(new DataBufferHeap(num_bytes_plus_nul_char, '\0'));
if (data_heap_ap.get())
{
@@ -752,8 +755,8 @@ File::Read (size_t &num_bytes, off_t &offset, bool null_terminate, DataBufferSP
{
// Make sure we read exactly what we asked for and if we got
// less, adjust the array
- if (num_bytes < data_heap_ap->GetByteSize())
- data_heap_ap->SetByteSize(num_bytes);
+ if (num_bytes_plus_nul_char < data_heap_ap->GetByteSize())
+ data_heap_ap->SetByteSize(num_bytes_plus_nul_char);
data_buffer_sp.reset(data_heap_ap.release());
return error;
}
diff --git a/source/Host/common/FileSpec.cpp b/source/Host/common/FileSpec.cpp
index 0af0556d30c9..6a6de53cd311 100644
--- a/source/Host/common/FileSpec.cpp
+++ b/source/Host/common/FileSpec.cpp
@@ -65,7 +65,7 @@ FileSpec::ResolveUsername (llvm::SmallVectorImpl<char> &path)
if (path.empty() || path[0] != '~')
return;
- llvm::StringRef path_str(path.data());
+ llvm::StringRef path_str(path.data(), path.size());
size_t slash_pos = path_str.find_first_of("/", 1);
if (slash_pos == 1 || path.size() == 1)
{
@@ -240,6 +240,12 @@ void FileSpec::Normalize(llvm::SmallVectorImpl<char> &path, PathSyntax syntax)
return;
std::replace(path.begin(), path.end(), '\\', '/');
+ // Windows path can have \\ slashes which can be changed by replace
+ // call above to //. Here we remove the duplicate.
+ auto iter = std::unique ( path.begin(), path.end(),
+ []( char &c1, char &c2 ){
+ return (c1 == '/' && c2 == '/');});
+ path.erase(iter, path.end());
}
void FileSpec::DeNormalize(llvm::SmallVectorImpl<char> &path, PathSyntax syntax)
@@ -1330,8 +1336,7 @@ FileSpec::IsSourceImplementationFile () const
ConstString extension (GetFileNameExtension());
if (extension)
{
- static RegularExpression g_source_file_regex ("^(c|m|mm|cpp|c\\+\\+|cxx|cc|cp|s|asm|f|f77|f90|f95|f03|for|ftn|fpp|ada|adb|ads)$",
- REG_EXTENDED | REG_ICASE);
+ static RegularExpression g_source_file_regex ("^([cC]|[mM]|[mM][mM]|[cC][pP][pP]|[cC]\\+\\+|[cC][xX][xX]|[cC][cC]|[cC][pP]|[sS]|[aA][sS][mM]|[fF]|[fF]77|[fF]90|[fF]95|[fF]03|[fF][oO][rR]|[fF][tT][nN]|[fF][pP][pP]|[aA][dD][aA]|[aA][dD][bB]|[aA][dD][sS])$");
return g_source_file_regex.Execute (extension.GetCString());
}
return false;
diff --git a/source/Host/common/Host.cpp b/source/Host/common/Host.cpp
index c8daa175d1bd..30f5c8683060 100644
--- a/source/Host/common/Host.cpp
+++ b/source/Host/common/Host.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
// C includes
#include <errno.h>
#include <limits.h>
@@ -48,20 +46,21 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Core/ArchSpec.h"
-#include "lldb/Core/Debugger.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
-#include "lldb/Core/Module.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostProcess.h"
#include "lldb/Host/MonitoringProcessLauncher.h"
+#include "lldb/Host/Predicate.h"
#include "lldb/Host/ProcessLauncher.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/lldb-private-forward.h"
+#include "llvm/Support/FileSystem.h"
#include "lldb/Target/FileAction.h"
#include "lldb/Target/ProcessLaunchInfo.h"
-#include "lldb/Target/TargetList.h"
+#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/CleanUp.h"
+#include "llvm/ADT/SmallString.h"
#if defined(_WIN32)
#include "lldb/Host/windows/ProcessLauncherWindows.h"
@@ -170,7 +169,7 @@ MonitorChildProcessThreadFunction (void *arg)
{
log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
if (log)
- log->Printf("%s ::wait_pid (pid = %" PRIi32 ", &status, options = %i)...", function, pid, options);
+ log->Printf("%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...", function, pid, options);
// Wait for all child processes
#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
@@ -233,9 +232,9 @@ MonitorChildProcessThreadFunction (void *arg)
if (log)
log->Printf ("%s ::waitpid (pid = %" PRIi32 ", &status, options = %i) => pid = %" PRIi32 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
function,
- wait_pid,
- options,
pid,
+ options,
+ wait_pid,
status,
status_cstr,
signal,
@@ -1053,12 +1052,6 @@ Host::SetCrashDescription (const char *description)
{
}
-lldb::pid_t
-Host::LaunchApplication (const FileSpec &app_file_spec)
-{
- return LLDB_INVALID_PROCESS_ID;
-}
-
#endif
#if !defined (__linux__) && !defined (__FreeBSD__) && !defined (__NetBSD__)
diff --git a/source/Host/common/HostInfoBase.cpp b/source/Host/common/HostInfoBase.cpp
index d65b79698384..9816c1ebf080 100644
--- a/source/Host/common/HostInfoBase.cpp
+++ b/source/Host/common/HostInfoBase.cpp
@@ -23,60 +23,56 @@
#include "llvm/Support/raw_ostream.h"
#include <thread>
+#include <mutex> // std::once
using namespace lldb;
using namespace lldb_private;
namespace
{
-void
-CleanupProcessSpecificLLDBTempDir()
-{
- // Get the process specific LLDB temporary directory and delete it.
- FileSpec tmpdir_file_spec;
- if (!HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
- return;
-
- // Remove the LLDB temporary directory if we have one. Set "recurse" to
- // true to all files that were created for the LLDB process can be cleaned up.
- FileSystem::DeleteDirectory(tmpdir_file_spec.GetDirectory().GetCString(), true);
-}
+ void
+ CleanupProcessSpecificLLDBTempDir()
+ {
+ // Get the process specific LLDB temporary directory and delete it.
+ FileSpec tmpdir_file_spec;
+ if (!HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
+ return;
+
+ // Remove the LLDB temporary directory if we have one. Set "recurse" to
+ // true to all files that were created for the LLDB process can be cleaned up.
+ FileSystem::DeleteDirectory(tmpdir_file_spec.GetDirectory().GetCString(), true);
+ }
-struct HostInfoBaseFields
-{
- uint32_t m_number_cpus;
- std::string m_vendor_string;
- std::string m_os_string;
- std::string m_host_triple;
-
- ArchSpec m_host_arch_32;
- ArchSpec m_host_arch_64;
-
- FileSpec m_lldb_so_dir;
- FileSpec m_lldb_support_exe_dir;
- FileSpec m_lldb_headers_dir;
- FileSpec m_lldb_python_dir;
- FileSpec m_lldb_clang_resource_dir;
- FileSpec m_lldb_system_plugin_dir;
- FileSpec m_lldb_user_plugin_dir;
- FileSpec m_lldb_tmp_dir;
-};
-
-HostInfoBaseFields *g_fields = nullptr;
-}
+ //----------------------------------------------------------------------
+ // The HostInfoBaseFields is a work around for windows not supporting
+ // static variables correctly in a thread safe way. Really each of the
+ // variables in HostInfoBaseFields should live in the functions in which
+ // they are used and each one should be static, but the work around is
+ // in place to avoid this restriction. Ick.
+ //----------------------------------------------------------------------
-#define COMPUTE_LLDB_PATH(compute_function, member_var) \
- { \
- static bool is_initialized = false; \
- static bool success = false; \
- if (!is_initialized) \
- { \
- is_initialized = true; \
- success = HostInfo::compute_function(member_var); \
- } \
- if (success) \
- result = &member_var; \
- }
+ struct HostInfoBaseFields
+ {
+ uint32_t m_number_cpus;
+ std::string m_vendor_string;
+ std::string m_os_string;
+ std::string m_host_triple;
+
+ ArchSpec m_host_arch_32;
+ ArchSpec m_host_arch_64;
+
+ FileSpec m_lldb_so_dir;
+ FileSpec m_lldb_support_exe_dir;
+ FileSpec m_lldb_headers_dir;
+ FileSpec m_lldb_python_dir;
+ FileSpec m_lldb_clang_resource_dir;
+ FileSpec m_lldb_system_plugin_dir;
+ FileSpec m_lldb_user_plugin_dir;
+ FileSpec m_lldb_tmp_dir;
+ };
+
+ HostInfoBaseFields *g_fields = nullptr;
+}
void
HostInfoBase::Initialize()
@@ -87,13 +83,10 @@ HostInfoBase::Initialize()
uint32_t
HostInfoBase::GetNumberCPUS()
{
- static bool is_initialized = false;
- if (!is_initialized)
- {
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
g_fields->m_number_cpus = std::thread::hardware_concurrency();
- is_initialized = true;
- }
-
+ });
return g_fields->m_number_cpus;
}
@@ -106,53 +99,40 @@ HostInfoBase::GetMaxThreadNameLength()
llvm::StringRef
HostInfoBase::GetVendorString()
{
- static bool is_initialized = false;
- if (!is_initialized)
- {
- const ArchSpec &host_arch = HostInfo::GetArchitecture();
- const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName();
- g_fields->m_vendor_string.assign(str_ref.begin(), str_ref.end());
- is_initialized = true;
- }
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+ g_fields->m_vendor_string = std::move(HostInfo::GetArchitecture().GetTriple().getVendorName().str());
+ });
return g_fields->m_vendor_string;
}
llvm::StringRef
HostInfoBase::GetOSString()
{
- static bool is_initialized = false;
- if (!is_initialized)
- {
- const ArchSpec &host_arch = HostInfo::GetArchitecture();
- const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName();
- g_fields->m_os_string.assign(str_ref.begin(), str_ref.end());
- is_initialized = true;
- }
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+ g_fields->m_os_string = std::move(HostInfo::GetArchitecture().GetTriple().getOSName());
+ });
return g_fields->m_os_string;
}
llvm::StringRef
HostInfoBase::GetTargetTriple()
{
- static bool is_initialized = false;
- if (!is_initialized)
- {
- const ArchSpec &host_arch = HostInfo::GetArchitecture();
- g_fields->m_host_triple = host_arch.GetTriple().getTriple();
- is_initialized = true;
- }
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+ g_fields->m_host_triple = HostInfo::GetArchitecture().GetTriple().getTriple();
+ });
return g_fields->m_host_triple;
}
const ArchSpec &
HostInfoBase::GetArchitecture(ArchitectureKind arch_kind)
{
- static bool is_initialized = false;
- if (!is_initialized)
- {
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
HostInfo::ComputeHostArchitectureSupport(g_fields->m_host_arch_32, g_fields->m_host_arch_64);
- is_initialized = true;
- }
+ });
// If an explicit 32 or 64-bit architecture was requested, return that.
if (arch_kind == eArchKind32)
@@ -174,52 +154,123 @@ HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec)
return false;
#endif
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
FileSpec *result = nullptr;
switch (type)
{
case lldb::ePathTypeLLDBShlibDir:
- COMPUTE_LLDB_PATH(ComputeSharedLibraryDirectory, g_fields->m_lldb_so_dir)
- if (log)
- log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", g_fields->m_lldb_so_dir.GetPath().c_str());
+ {
+ static std::once_flag g_once_flag;
+ static bool success = false;
+ std::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeSharedLibraryDirectory (g_fields->m_lldb_so_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (log)
+ log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", g_fields->m_lldb_so_dir.GetPath().c_str());
+ });
+ if (success)
+ result = &g_fields->m_lldb_so_dir;
+ }
break;
case lldb::ePathTypeSupportExecutableDir:
- COMPUTE_LLDB_PATH(ComputeSupportExeDirectory, g_fields->m_lldb_support_exe_dir)
- if (log)
- log->Printf("HostInfoBase::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'",
- g_fields->m_lldb_support_exe_dir.GetPath().c_str());
+ {
+ static std::once_flag g_once_flag;
+ static bool success = false;
+ std::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeSupportExeDirectory (g_fields->m_lldb_support_exe_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (log)
+ log->Printf("HostInfoBase::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'",
+ g_fields->m_lldb_support_exe_dir.GetPath().c_str());
+ });
+ if (success)
+ result = &g_fields->m_lldb_support_exe_dir;
+ }
break;
case lldb::ePathTypeHeaderDir:
- COMPUTE_LLDB_PATH(ComputeHeaderDirectory, g_fields->m_lldb_headers_dir)
- if (log)
- log->Printf("HostInfoBase::GetLLDBPath(ePathTypeHeaderDir) => '%s'", g_fields->m_lldb_headers_dir.GetPath().c_str());
+ {
+ static std::once_flag g_once_flag;
+ static bool success = false;
+ std::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeHeaderDirectory (g_fields->m_lldb_headers_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (log)
+ log->Printf("HostInfoBase::GetLLDBPath(ePathTypeHeaderDir) => '%s'", g_fields->m_lldb_headers_dir.GetPath().c_str());
+ });
+ if (success)
+ result = &g_fields->m_lldb_headers_dir;
+ }
break;
case lldb::ePathTypePythonDir:
- COMPUTE_LLDB_PATH(ComputePythonDirectory, g_fields->m_lldb_python_dir)
- if (log)
- log->Printf("HostInfoBase::GetLLDBPath(ePathTypePythonDir) => '%s'", g_fields->m_lldb_python_dir.GetPath().c_str());
+ {
+ static std::once_flag g_once_flag;
+ static bool success = false;
+ std::call_once(g_once_flag, []() {
+ success = HostInfo::ComputePythonDirectory (g_fields->m_lldb_python_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (log)
+ log->Printf("HostInfoBase::GetLLDBPath(ePathTypePythonDir) => '%s'", g_fields->m_lldb_python_dir.GetPath().c_str());
+ });
+ if (success)
+ result = &g_fields->m_lldb_python_dir;
+ }
break;
case lldb::ePathTypeClangDir:
- COMPUTE_LLDB_PATH(ComputeClangDirectory, g_fields->m_lldb_clang_resource_dir)
- if (log)
- log->Printf("HostInfoBase::GetLLDBPath(ePathTypeClangResourceDir) => '%s'", g_fields->m_lldb_clang_resource_dir.GetPath().c_str());
+ {
+ static std::once_flag g_once_flag;
+ static bool success = false;
+ std::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeClangDirectory (g_fields->m_lldb_clang_resource_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (log)
+ log->Printf("HostInfoBase::GetLLDBPath(ePathTypeClangResourceDir) => '%s'", g_fields->m_lldb_clang_resource_dir.GetPath().c_str());
+ });
+ if (success)
+ result = &g_fields->m_lldb_clang_resource_dir;
+ }
break;
case lldb::ePathTypeLLDBSystemPlugins:
- COMPUTE_LLDB_PATH(ComputeSystemPluginsDirectory, g_fields->m_lldb_system_plugin_dir)
- if (log)
- log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'",
- g_fields->m_lldb_system_plugin_dir.GetPath().c_str());
+ {
+ static std::once_flag g_once_flag;
+ static bool success = false;
+ std::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeSystemPluginsDirectory (g_fields->m_lldb_system_plugin_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (log)
+ log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'",
+ g_fields->m_lldb_system_plugin_dir.GetPath().c_str());
+ });
+ if (success)
+ result = &g_fields->m_lldb_system_plugin_dir;
+ }
break;
case lldb::ePathTypeLLDBUserPlugins:
- COMPUTE_LLDB_PATH(ComputeUserPluginsDirectory, g_fields->m_lldb_user_plugin_dir)
- if (log)
- log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'",
- g_fields->m_lldb_user_plugin_dir.GetPath().c_str());
+ {
+ static std::once_flag g_once_flag;
+ static bool success = false;
+ std::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeUserPluginsDirectory (g_fields->m_lldb_user_plugin_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (log)
+ log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'",
+ g_fields->m_lldb_user_plugin_dir.GetPath().c_str());
+ });
+ if (success)
+ result = &g_fields->m_lldb_user_plugin_dir;
+ }
break;
case lldb::ePathTypeLLDBTempSystemDir:
- COMPUTE_LLDB_PATH(ComputeTempFileDirectory, g_fields->m_lldb_tmp_dir)
- if (log)
- log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_fields->m_lldb_tmp_dir.GetPath().c_str());
+ {
+ static std::once_flag g_once_flag;
+ static bool success = false;
+ std::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeTempFileDirectory (g_fields->m_lldb_tmp_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (log)
+ log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_fields->m_lldb_tmp_dir.GetPath().c_str());
+ });
+ if (success)
+ result = &g_fields->m_lldb_tmp_dir;
+ }
break;
}
@@ -327,6 +378,7 @@ HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_6
arch_32.SetTriple(triple);
break;
+ case llvm::Triple::ppc64:
case llvm::Triple::x86_64:
arch_64.SetTriple(triple);
arch_32.SetTriple(triple.get32BitArchVariant());
@@ -335,7 +387,6 @@ HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_6
case llvm::Triple::aarch64:
case llvm::Triple::mips64:
case llvm::Triple::sparcv9:
- case llvm::Triple::ppc64:
arch_64.SetTriple(triple);
break;
}
diff --git a/source/Host/common/NativeBreakpoint.cpp b/source/Host/common/NativeBreakpoint.cpp
index 284d7d11d6ce..622b4eab1726 100644
--- a/source/Host/common/NativeBreakpoint.cpp
+++ b/source/Host/common/NativeBreakpoint.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "NativeBreakpoint.h"
+#include "lldb/Host/common/NativeBreakpoint.h"
#include "lldb/lldb-defines.h"
#include "lldb/Core/Error.h"
diff --git a/source/Host/common/NativeBreakpointList.cpp b/source/Host/common/NativeBreakpointList.cpp
index ecd0624bde09..94d0b3756da4 100644
--- a/source/Host/common/NativeBreakpointList.cpp
+++ b/source/Host/common/NativeBreakpointList.cpp
@@ -1,4 +1,4 @@
-//===-- NativeBreakpointList.h ----------------------------------*- C++ -*-===//
+//===-- NativeBreakpointList.cpp --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,11 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "NativeBreakpointList.h"
+#include "lldb/Host/common/NativeBreakpointList.h"
#include "lldb/Core/Log.h"
-#include "NativeBreakpoint.h"
+#include "lldb/Host/common/NativeBreakpoint.h"
using namespace lldb;
using namespace lldb_private;
diff --git a/source/Host/common/NativeProcessProtocol.cpp b/source/Host/common/NativeProcessProtocol.cpp
index e192f19a8896..ff7310d2d45a 100644
--- a/source/Host/common/NativeProcessProtocol.cpp
+++ b/source/Host/common/NativeProcessProtocol.cpp
@@ -7,17 +7,17 @@
//
//===----------------------------------------------------------------------===//
-#include "NativeProcessProtocol.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
-#include "lldb/Target/NativeRegisterContext.h"
+#include "lldb/Host/common/NativeRegisterContext.h"
-#include "NativeThreadProtocol.h"
-#include "SoftwareBreakpoint.h"
+#include "lldb/Host/common/NativeThreadProtocol.h"
+#include "lldb/Host/common/SoftwareBreakpoint.h"
using namespace lldb;
using namespace lldb_private;
@@ -39,6 +39,7 @@ NativeProcessProtocol::NativeProcessProtocol (lldb::pid_t pid) :
m_delegates_mutex (Mutex::eMutexTypeRecursive),
m_delegates (),
m_breakpoint_list (),
+ m_watchpoint_list (),
m_terminal_fd (-1),
m_stop_id (0)
{
@@ -159,6 +160,12 @@ NativeProcessProtocol::GetByteOrder (lldb::ByteOrder &byte_order) const
return true;
}
+const NativeWatchpointList::WatchpointMap&
+NativeProcessProtocol::GetWatchpointMap () const
+{
+ return m_watchpoint_list.GetWatchpointMap();
+}
+
uint32_t
NativeProcessProtocol::GetMaxWatchpoints () const
{
@@ -199,9 +206,6 @@ NativeProcessProtocol::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t w
Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
- // FIXME save the watchpoint on the set of process watchpoint vars
- // so we can add them to a thread each time a new thread is registered.
-
// Update the thread list
UpdateThreads ();
@@ -261,15 +265,12 @@ NativeProcessProtocol::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t w
return thread_error;
}
}
- return Error ();
+ return m_watchpoint_list.Add (addr, size, watch_flags, hardware);
}
Error
NativeProcessProtocol::RemoveWatchpoint (lldb::addr_t addr)
{
- // FIXME remove the watchpoint on the set of process watchpoint vars
- // so we can add them to a thread each time a new thread is registered.
-
// Update the thread list
UpdateThreads ();
@@ -292,7 +293,8 @@ NativeProcessProtocol::RemoveWatchpoint (lldb::addr_t addr)
overall_error = thread_error;
}
}
- return overall_error;
+ const Error error = m_watchpoint_list.Remove(addr);
+ return overall_error.Fail() ? overall_error : error;
}
bool
@@ -400,6 +402,10 @@ void
NativeProcessProtocol::SetState (lldb::StateType state, bool notify_delegates)
{
Mutex::Locker locker (m_state_mutex);
+
+ if (state == m_state)
+ return;
+
m_state = state;
if (StateIsStoppedState (state, false))
diff --git a/source/Target/NativeRegisterContext.cpp b/source/Host/common/NativeRegisterContext.cpp
index d84e2279a459..42a9c91a63a0 100644
--- a/source/Target/NativeRegisterContext.cpp
+++ b/source/Host/common/NativeRegisterContext.cpp
@@ -7,15 +7,15 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Target/NativeRegisterContext.h"
+#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/lldb-private-log.h"
-#include "Host/common/NativeProcessProtocol.h"
-#include "Host/common/NativeThreadProtocol.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Host/common/NativeThreadProtocol.h"
using namespace lldb;
using namespace lldb_private;
@@ -297,6 +297,12 @@ NativeRegisterContext::ClearHardwareWatchpoint (uint32_t hw_index)
return false;
}
+Error
+NativeRegisterContext::ClearAllHardwareWatchpoints ()
+{
+ return Error ("not implemented");
+}
+
bool
NativeRegisterContext::HardwareSingleStep (bool enable)
{
diff --git a/source/Target/NativeRegisterContextRegisterInfo.cpp b/source/Host/common/NativeRegisterContextRegisterInfo.cpp
index e37014546646..0d7c6eced757 100644
--- a/source/Target/NativeRegisterContextRegisterInfo.cpp
+++ b/source/Host/common/NativeRegisterContextRegisterInfo.cpp
@@ -9,7 +9,7 @@
#include "lldb/lldb-types.h"
#include "lldb/lldb-private-forward.h"
-#include "lldb/Target/NativeRegisterContextRegisterInfo.h"
+#include "lldb/Host/common/NativeRegisterContextRegisterInfo.h"
using namespace lldb_private;
@@ -28,6 +28,12 @@ NativeRegisterContextRegisterInfo::GetRegisterCount () const
return m_register_info_interface_up->GetRegisterCount ();
}
+uint32_t
+NativeRegisterContextRegisterInfo::GetUserRegisterCount () const
+{
+ return m_register_info_interface_up->GetUserRegisterCount ();
+}
+
const RegisterInfo *
NativeRegisterContextRegisterInfo::GetRegisterInfoAtIndex (uint32_t reg_index) const
{
diff --git a/source/Host/common/NativeThreadProtocol.cpp b/source/Host/common/NativeThreadProtocol.cpp
index 6cef5b1fa2d2..ea406e9ef2c6 100644
--- a/source/Host/common/NativeThreadProtocol.cpp
+++ b/source/Host/common/NativeThreadProtocol.cpp
@@ -7,11 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "NativeThreadProtocol.h"
+#include "lldb/Host/common/NativeThreadProtocol.h"
-#include "NativeProcessProtocol.h"
-#include "lldb/Target/NativeRegisterContext.h"
-#include "SoftwareBreakpoint.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Host/common/NativeRegisterContext.h"
+#include "lldb/Host/common/SoftwareBreakpoint.h"
using namespace lldb;
using namespace lldb_private;
@@ -73,25 +73,3 @@ NativeThreadProtocol::GetProcess ()
{
return m_process_wp.lock ();
}
-
-uint32_t
-NativeThreadProtocol::TranslateStopInfoToGdbSignal (const ThreadStopInfo &stop_info) const
-{
- // Default: no translation. Do the real translation where there
- // is access to the host signal numbers.
- switch (stop_info.reason)
- {
- case eStopReasonSignal:
- return stop_info.details.signal.signo;
- break;
-
- case eStopReasonException:
- // FIXME verify the way to specify pass-thru here.
- return static_cast<uint32_t> (stop_info.details.exception.type);
- break;
-
- default:
- assert (0 && "unexpected stop_info.reason found");
- return 0;
- }
-}
diff --git a/source/Host/common/NativeWatchpointList.cpp b/source/Host/common/NativeWatchpointList.cpp
new file mode 100644
index 000000000000..209d213b8e50
--- /dev/null
+++ b/source/Host/common/NativeWatchpointList.cpp
@@ -0,0 +1,35 @@
+//===-- NativeWatchpointList.cpp --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/common/NativeWatchpointList.h"
+
+#include "lldb/Core/Log.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+Error
+NativeWatchpointList::Add (addr_t addr, size_t size, uint32_t watch_flags, bool hardware)
+{
+ m_watchpoints[addr] = {addr, size, watch_flags, hardware};
+ return Error ();
+}
+
+Error
+NativeWatchpointList::Remove (addr_t addr)
+{
+ m_watchpoints.erase(addr);
+ return Error ();
+}
+
+const NativeWatchpointList::WatchpointMap&
+NativeWatchpointList::GetWatchpointMap () const
+{
+ return m_watchpoints;
+}
diff --git a/source/Host/common/Socket.cpp b/source/Host/common/Socket.cpp
index a6118eef7b79..b5559fffb45d 100644
--- a/source/Host/common/Socket.cpp
+++ b/source/Host/common/Socket.cpp
@@ -15,8 +15,8 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/SocketAddress.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Host/TimeValue.h"
-#include "lldb/Interpreter/Args.h"
#ifdef __ANDROID_NDK__
#include <linux/tcp.h>
@@ -190,7 +190,7 @@ Error Socket::TcpListen(llvm::StringRef host_and_port, bool child_processes_inhe
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
if (log)
- log->Printf ("ConnectionFileDescriptor::SocketListen (%s)", host_and_port.data());
+ log->Printf ("Socket::TcpListen (%s)", host_and_port.data());
std::string host_str;
std::string port_str;
@@ -222,7 +222,7 @@ Error Socket::TcpListen(llvm::StringRef host_and_port, bool child_processes_inhe
// as port zero is a special code for "find an open port
// for me".
if (port == 0)
- port = listen_socket->GetPortNumber();
+ port = listen_socket->GetLocalPortNumber();
// Set the port predicate since when doing a listen://<host>:<port>
// it often needs to accept the incoming connection which is a blocking
@@ -230,7 +230,7 @@ Error Socket::TcpListen(llvm::StringRef host_and_port, bool child_processes_inhe
// us to wait for the port predicate to be set to a non-zero value from
// another thread in an efficient manor.
if (predicate)
- predicate->SetValue(port, eBroadcastAlways);
+ predicate->SetValue (port, eBroadcastAlways);
socket = listen_socket.release();
}
@@ -533,13 +533,18 @@ Socket::DecodeHostAndPort(llvm::StringRef host_and_port,
if (regex_match.GetMatchAtIndex (host_and_port.data(), 1, host_str) &&
regex_match.GetMatchAtIndex (host_and_port.data(), 2, port_str))
{
- port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN);
- if (port != INT32_MIN)
+ bool ok = false;
+ port = StringConvert::ToUInt32 (port_str.c_str(), UINT32_MAX, 10, &ok);
+ if (ok && port < UINT16_MAX)
{
if (error_ptr)
error_ptr->Clear();
return true;
}
+ // port is too large
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port.data());
+ return false;
}
}
@@ -547,10 +552,13 @@ Socket::DecodeHostAndPort(llvm::StringRef host_and_port,
// a port with an empty host.
host_str.clear();
port_str.clear();
- port = Args::StringToSInt32(host_and_port.data(), INT32_MIN);
- if (port != INT32_MIN)
+ bool ok = false;
+ port = StringConvert::ToUInt32 (host_and_port.data(), UINT32_MAX, 10, &ok);
+ if (ok && port < UINT16_MAX)
{
port_str = host_and_port;
+ if (error_ptr)
+ error_ptr->Clear();
return true;
}
@@ -688,7 +696,7 @@ int Socket::SetOption(int level, int option_name, int option_value)
return ::setsockopt(m_socket, level, option_name, option_value_p, sizeof(option_value));
}
-uint16_t Socket::GetPortNumber(const NativeSocket& socket)
+uint16_t Socket::GetLocalPortNumber(const NativeSocket& socket)
{
// We bound to port zero, so we need to figure out which port we actually bound to
if (socket >= 0)
@@ -702,7 +710,47 @@ uint16_t Socket::GetPortNumber(const NativeSocket& socket)
}
// Return the port number that is being used by the socket.
-uint16_t Socket::GetPortNumber() const
+uint16_t Socket::GetLocalPortNumber() const
{
- return GetPortNumber(m_socket);
+ return GetLocalPortNumber (m_socket);
}
+
+std::string Socket::GetLocalIPAddress () const
+{
+ // We bound to port zero, so we need to figure out which port we actually bound to
+ if (m_socket >= 0)
+ {
+ SocketAddress sock_addr;
+ socklen_t sock_addr_len = sock_addr.GetMaxLength ();
+ if (::getsockname (m_socket, sock_addr, &sock_addr_len) == 0)
+ return sock_addr.GetIPAddress ();
+ }
+ return "";
+}
+
+uint16_t Socket::GetRemotePortNumber () const
+{
+ if (m_socket >= 0)
+ {
+ SocketAddress sock_addr;
+ socklen_t sock_addr_len = sock_addr.GetMaxLength ();
+ if (::getpeername (m_socket, sock_addr, &sock_addr_len) == 0)
+ return sock_addr.GetPort ();
+ }
+ return 0;
+}
+
+std::string Socket::GetRemoteIPAddress () const
+{
+ // We bound to port zero, so we need to figure out which port we actually bound to
+ if (m_socket >= 0)
+ {
+ SocketAddress sock_addr;
+ socklen_t sock_addr_len = sock_addr.GetMaxLength ();
+ if (::getpeername (m_socket, sock_addr, &sock_addr_len) == 0)
+ return sock_addr.GetIPAddress ();
+ }
+ return "";
+}
+
+
diff --git a/source/Host/common/SocketAddress.cpp b/source/Host/common/SocketAddress.cpp
index 6231631934df..fd7fbac952e3 100644
--- a/source/Host/common/SocketAddress.cpp
+++ b/source/Host/common/SocketAddress.cpp
@@ -21,6 +21,58 @@
// Other libraries and framework includes
// Project includes
+// WindowsXP needs an inet_ntop implementation
+#ifdef _WIN32
+
+#ifndef INET6_ADDRSTRLEN // might not be defined in older Windows SDKs
+#define INET6_ADDRSTRLEN 46
+#endif
+
+// TODO: implement shortened form "::" for runs of zeros
+const char* inet_ntop(int af, const void * src,
+ char * dst, socklen_t size)
+{
+ if (size==0)
+ {
+ return nullptr;
+ }
+
+ switch (af)
+ {
+ case AF_INET:
+ {
+ {
+ const char* formatted = inet_ntoa(*static_cast<const in_addr*>(src));
+ if (formatted && strlen(formatted) < size)
+ {
+ strncpy(dst, formatted, size);
+ return dst;
+ }
+ }
+ return nullptr;
+ case AF_INET6:
+ {
+ char tmp[INET6_ADDRSTRLEN] = {0};
+ const uint16_t* src16 = static_cast<const uint16_t*>(src);
+ int full_size = _snprintf(tmp, sizeof(tmp),
+ "%x:%x:%x:%x:%x:%x:%x:%x",
+ ntohs(src16[0]), ntohs(src16[1]), ntohs(src16[2]), ntohs(src16[3]),
+ ntohs(src16[4]), ntohs(src16[5]), ntohs(src16[6]), ntohs(src16[7])
+ );
+ if (full_size < static_cast<int>(size))
+ {
+ strncpy(dst,tmp,size);
+ return dst;
+ }
+ return nullptr;
+ }
+ }
+ }
+ return nullptr;
+}
+#endif
+
+
using namespace lldb_private;
//----------------------------------------------------------------------
@@ -124,6 +176,26 @@ SocketAddress::SetFamily (sa_family_t family)
#endif
}
+std::string
+SocketAddress::GetIPAddress () const
+{
+ char str[INET6_ADDRSTRLEN] = {0};
+ switch (GetFamily())
+ {
+ case AF_INET:
+ if (inet_ntop(GetFamily(), &m_socket_addr.sa_ipv4.sin_addr, str, sizeof(str)))
+ {
+ return str;
+ }
+ case AF_INET6:
+ if (inet_ntop(GetFamily(), &m_socket_addr.sa_ipv6.sin6_addr, str, sizeof(str)))
+ {
+ return str;
+ }
+ }
+ return "";
+}
+
uint16_t
SocketAddress::GetPort () const
{
diff --git a/source/Host/common/SoftwareBreakpoint.cpp b/source/Host/common/SoftwareBreakpoint.cpp
index d9d1fa67156f..67f472b88f5c 100644
--- a/source/Host/common/SoftwareBreakpoint.cpp
+++ b/source/Host/common/SoftwareBreakpoint.cpp
@@ -7,14 +7,14 @@
//
//===----------------------------------------------------------------------===//
-#include "SoftwareBreakpoint.h"
+#include "lldb/Host/common/SoftwareBreakpoint.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
#include "lldb/Host/Debug.h"
#include "lldb/Host/Mutex.h"
-#include "NativeProcessProtocol.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
using namespace lldb_private;
diff --git a/source/Host/common/StringConvert.cpp b/source/Host/common/StringConvert.cpp
new file mode 100644
index 000000000000..0a8e75f4b877
--- /dev/null
+++ b/source/Host/common/StringConvert.cpp
@@ -0,0 +1,93 @@
+//===-- StringConvert.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+#include <stdlib.h>
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Host/StringConvert.h"
+
+namespace lldb_private {
+
+namespace StringConvert {
+
+int32_t
+ToSInt32 (const char *s, int32_t fail_value, int base, bool *success_ptr)
+{
+ if (s && s[0])
+ {
+ char *end = nullptr;
+ const long sval = ::strtol (s, &end, base);
+ if (*end == '\0')
+ {
+ if (success_ptr)
+ *success_ptr = ((sval <= INT32_MAX) && (sval >= INT32_MIN));
+ return (int32_t)sval; // All characters were used, return the result
+ }
+ }
+ if (success_ptr) *success_ptr = false;
+ return fail_value;
+}
+
+uint32_t
+ToUInt32 (const char *s, uint32_t fail_value, int base, bool *success_ptr)
+{
+ if (s && s[0])
+ {
+ char *end = nullptr;
+ const unsigned long uval = ::strtoul (s, &end, base);
+ if (*end == '\0')
+ {
+ if (success_ptr)
+ *success_ptr = (uval <= UINT32_MAX);
+ return (uint32_t)uval; // All characters were used, return the result
+ }
+ }
+ if (success_ptr) *success_ptr = false;
+ return fail_value;
+}
+
+int64_t
+ToSInt64 (const char *s, int64_t fail_value, int base, bool *success_ptr)
+{
+ if (s && s[0])
+ {
+ char *end = nullptr;
+ int64_t uval = ::strtoll (s, &end, base);
+ if (*end == '\0')
+ {
+ if (success_ptr) *success_ptr = true;
+ return uval; // All characters were used, return the result
+ }
+ }
+ if (success_ptr) *success_ptr = false;
+ return fail_value;
+}
+
+uint64_t
+ToUInt64 (const char *s, uint64_t fail_value, int base, bool *success_ptr)
+{
+ if (s && s[0])
+ {
+ char *end = nullptr;
+ uint64_t uval = ::strtoull (s, &end, base);
+ if (*end == '\0')
+ {
+ if (success_ptr) *success_ptr = true;
+ return uval; // All characters were used, return the result
+ }
+ }
+ if (success_ptr) *success_ptr = false;
+ return fail_value;
+}
+
+}
+}
diff --git a/source/Host/common/ThreadLauncher.cpp b/source/Host/common/ThreadLauncher.cpp
index ec7da325bf92..c19a23361d81 100644
--- a/source/Host/common/ThreadLauncher.cpp
+++ b/source/Host/common/ThreadLauncher.cpp
@@ -38,6 +38,16 @@ ThreadLauncher::LaunchThread(llvm::StringRef name, lldb::thread_func_t thread_fu
error.SetError(::GetLastError(), eErrorTypeWin32);
#else
+
+ // ASAN instrumentation adds a lot of bookkeeping overhead on stack frames.
+#if __has_feature(address_sanitizer)
+ const size_t eight_megabytes = 8 * 1024 * 1024;
+ if (min_stack_byte_size < eight_megabytes)
+ {
+ min_stack_byte_size += eight_megabytes;
+ }
+#endif
+
pthread_attr_t *thread_attr_ptr = NULL;
pthread_attr_t thread_attr;
bool destroy_attr = false;
diff --git a/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
index 38ddc0a49220..fe70c33bf5ae 100644
--- a/source/Host/posix/ConnectionFileDescriptorPosix.cpp
+++ b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
@@ -19,6 +19,7 @@
#include "lldb/Host/IOObject.h"
#include "lldb/Host/SocketAddress.h"
#include "lldb/Host/Socket.h"
+#include "lldb/Host/StringConvert.h"
// C Includes
#include <errno.h>
@@ -41,6 +42,7 @@
#include "lldb/lldb-private-log.h"
#include "lldb/Core/Communication.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/Socket.h"
@@ -142,7 +144,7 @@ ConnectionFileDescriptor::Connect(const char *s, Error *error_ptr)
if (strstr(s, "listen://") == s)
{
// listen://HOST:PORT
- return SocketListen(s + strlen("listen://"), error_ptr);
+ return SocketListenAndAccept(s + strlen("listen://"), error_ptr);
}
else if (strstr(s, "accept://") == s)
{
@@ -173,7 +175,7 @@ ConnectionFileDescriptor::Connect(const char *s, Error *error_ptr)
// that is already opened (possibly from a service or other source).
s += strlen("fd://");
bool success = false;
- int fd = Args::StringToSInt32(s, -1, 0, &success);
+ int fd = StringConvert::ToSInt32(s, -1, 0, &success);
if (success)
{
@@ -219,6 +221,7 @@ ConnectionFileDescriptor::Connect(const char *s, Error *error_ptr)
m_read_sp.reset(new File(fd, false));
m_write_sp.reset(new File(fd, false));
}
+ m_uri.assign(s);
return eConnectionStatusSuccess;
}
}
@@ -351,6 +354,7 @@ ConnectionFileDescriptor::Disconnect(Error *error_ptr)
if (error_ptr)
*error_ptr = error.Fail() ? error : error2;
+ m_uri.clear();
m_shutting_down = false;
return status;
}
@@ -510,6 +514,12 @@ ConnectionFileDescriptor::Write(const void *src, size_t src_len, ConnectionStatu
return bytes_sent;
}
+std::string
+ConnectionFileDescriptor::GetURI()
+{
+ return m_uri;
+}
+
// This ConnectionFileDescriptor::BytesAvailable() uses select().
//
// PROS:
@@ -700,7 +710,12 @@ ConnectionFileDescriptor::NamedSocketAccept(const char *socket_name, Error *erro
*error_ptr = error;
m_write_sp.reset(socket);
m_read_sp = m_write_sp;
- return (error.Success()) ? eConnectionStatusSuccess : eConnectionStatusError;
+ if (error.Fail())
+ {
+ return eConnectionStatusError;
+ }
+ m_uri.assign(socket_name);
+ return eConnectionStatusSuccess;
}
ConnectionStatus
@@ -712,11 +727,16 @@ ConnectionFileDescriptor::NamedSocketConnect(const char *socket_name, Error *err
*error_ptr = error;
m_write_sp.reset(socket);
m_read_sp = m_write_sp;
- return (error.Success()) ? eConnectionStatusSuccess : eConnectionStatusError;
+ if (error.Fail())
+ {
+ return eConnectionStatusError;
+ }
+ m_uri.assign(socket_name);
+ return eConnectionStatusSuccess;
}
ConnectionStatus
-ConnectionFileDescriptor::SocketListen(const char *s, Error *error_ptr)
+ConnectionFileDescriptor::SocketListenAndAccept(const char *s, Error *error_ptr)
{
m_port_predicate.SetValue(0, eBroadcastNever);
@@ -741,7 +761,14 @@ ConnectionFileDescriptor::SocketListen(const char *s, Error *error_ptr)
m_write_sp.reset(socket);
m_read_sp = m_write_sp;
- return (error.Success()) ? eConnectionStatusSuccess : eConnectionStatusError;
+ if (error.Fail())
+ {
+ return eConnectionStatusError;
+ }
+ StreamString strm;
+ strm.Printf("connect://%s:%u",socket->GetRemoteIPAddress().c_str(), socket->GetRemotePortNumber());
+ m_uri.swap(strm.GetString());
+ return eConnectionStatusSuccess;
}
ConnectionStatus
@@ -753,7 +780,12 @@ ConnectionFileDescriptor::ConnectTCP(const char *s, Error *error_ptr)
*error_ptr = error;
m_write_sp.reset(socket);
m_read_sp = m_write_sp;
- return (error.Success()) ? eConnectionStatusSuccess : eConnectionStatusError;
+ if (error.Fail())
+ {
+ return eConnectionStatusError;
+ }
+ m_uri.assign(s);
+ return eConnectionStatusSuccess;
}
ConnectionStatus
@@ -766,7 +798,12 @@ ConnectionFileDescriptor::ConnectUDP(const char *s, Error *error_ptr)
*error_ptr = error;
m_write_sp.reset(send_socket);
m_read_sp.reset(recv_socket);
- return (error.Success()) ? eConnectionStatusSuccess : eConnectionStatusError;
+ if (error.Fail())
+ {
+ return eConnectionStatusError;
+ }
+ m_uri.assign(s);
+ return eConnectionStatusSuccess;
}
uint16_t
diff --git a/source/Host/posix/PipePosix.cpp b/source/Host/posix/PipePosix.cpp
index 02838ec5124e..1650f1e7979b 100644
--- a/source/Host/posix/PipePosix.cpp
+++ b/source/Host/posix/PipePosix.cpp
@@ -9,12 +9,16 @@
#include "lldb/Host/posix/PipePosix.h"
#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/HostInfo.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/FileSystem.h"
#include <functional>
#include <thread>
#include <errno.h>
#include <fcntl.h>
+#include <limits.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -183,6 +187,37 @@ PipePosix::CreateNew(llvm::StringRef name, bool child_process_inherit)
}
Error
+PipePosix::CreateWithUniqueName(llvm::StringRef prefix, bool child_process_inherit, llvm::SmallVectorImpl<char>& name)
+{
+ llvm::SmallString<PATH_MAX> named_pipe_path;
+ llvm::SmallString<PATH_MAX> pipe_spec((prefix + ".%%%%%%").str());
+ FileSpec tmpdir_file_spec;
+ tmpdir_file_spec.Clear();
+ if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
+ {
+ tmpdir_file_spec.AppendPathComponent(pipe_spec.c_str());
+ }
+ else
+ {
+ tmpdir_file_spec.AppendPathComponent("/tmp");
+ tmpdir_file_spec.AppendPathComponent(pipe_spec.c_str());
+ }
+
+ // It's possible that another process creates the target path after we've
+ // verified it's available but before we create it, in which case we
+ // should try again.
+ Error error;
+ do {
+ llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath().c_str(), named_pipe_path);
+ error = CreateNew(named_pipe_path, child_process_inherit);
+ } while (error.GetError() == EEXIST);
+
+ if (error.Success())
+ name = named_pipe_path;
+ return error;
+}
+
+Error
PipePosix::OpenAsReader(llvm::StringRef name, bool child_process_inherit)
{
if (CanRead() || CanWrite())
diff --git a/source/Interpreter/Args.cpp b/source/Interpreter/Args.cpp
index 93933802f57c..4f0219fb858b 100644
--- a/source/Interpreter/Args.cpp
+++ b/source/Interpreter/Args.cpp
@@ -19,14 +19,13 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/DataFormatters/FormatManager.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Process.h"
-//#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
-//#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
@@ -166,7 +165,7 @@ Args::SetCommandString (const char *command)
if (command && command[0])
{
static const char *k_space_separators = " \t";
- static const char *k_space_separators_with_slash_and_quotes = " \t \\'\"";
+ static const char *k_escapable_characters = " \t\\'\"";
const char *arg_end = nullptr;
const char *arg_pos;
for (arg_pos = command;
@@ -202,7 +201,7 @@ Args::SetCommandString (const char *command)
do
{
- arg_end = ::strcspn (arg_pos, k_space_separators_with_slash_and_quotes) + arg_pos;
+ arg_end = ::strcspn (arg_pos, k_escapable_characters) + arg_pos;
switch (arg_end[0])
{
@@ -216,7 +215,6 @@ Args::SetCommandString (const char *command)
arg.append (arg_piece_start);
arg_complete = true;
break;
-
case '\\':
// Backslash character
switch (arg_end[1])
@@ -228,22 +226,21 @@ Args::SetCommandString (const char *command)
break;
default:
- if (quote_char == '\0')
+ // Only consider this two-character sequence an escape sequence if we're unquoted and
+ // the character after the backslash is a whitelisted escapable character. Otherwise
+ // leave the character sequence untouched.
+ if (quote_char == '\0' && (nullptr != strchr(k_escapable_characters, arg_end[1])))
{
arg.append (arg_piece_start, arg_end - arg_piece_start);
- if (arg_end[1] != '\0')
- {
- arg.append (arg_end + 1, 1);
- arg_pos = arg_end + 2;
- arg_piece_start = arg_pos;
- }
+ arg.append (arg_end + 1, 1);
+ arg_pos = arg_end + 2;
+ arg_piece_start = arg_pos;
}
else
arg_pos = arg_end + 2;
break;
}
break;
-
case '"':
case '\'':
case '`':
@@ -722,77 +719,6 @@ Args::Clear ()
m_args_quote_char.clear();
}
-int32_t
-Args::StringToSInt32 (const char *s, int32_t fail_value, int base, bool *success_ptr)
-{
- if (s && s[0])
- {
- char *end = nullptr;
- const long sval = ::strtol (s, &end, base);
- if (*end == '\0')
- {
- if (success_ptr)
- *success_ptr = ((sval <= INT32_MAX) && (sval >= INT32_MIN));
- return (int32_t)sval; // All characters were used, return the result
- }
- }
- if (success_ptr) *success_ptr = false;
- return fail_value;
-}
-
-uint32_t
-Args::StringToUInt32 (const char *s, uint32_t fail_value, int base, bool *success_ptr)
-{
- if (s && s[0])
- {
- char *end = nullptr;
- const unsigned long uval = ::strtoul (s, &end, base);
- if (*end == '\0')
- {
- if (success_ptr)
- *success_ptr = (uval <= UINT32_MAX);
- return (uint32_t)uval; // All characters were used, return the result
- }
- }
- if (success_ptr) *success_ptr = false;
- return fail_value;
-}
-
-
-int64_t
-Args::StringToSInt64 (const char *s, int64_t fail_value, int base, bool *success_ptr)
-{
- if (s && s[0])
- {
- char *end = nullptr;
- int64_t uval = ::strtoll (s, &end, base);
- if (*end == '\0')
- {
- if (success_ptr) *success_ptr = true;
- return uval; // All characters were used, return the result
- }
- }
- if (success_ptr) *success_ptr = false;
- return fail_value;
-}
-
-uint64_t
-Args::StringToUInt64 (const char *s, uint64_t fail_value, int base, bool *success_ptr)
-{
- if (s && s[0])
- {
- char *end = nullptr;
- uint64_t uval = ::strtoull (s, &end, base);
- if (*end == '\0')
- {
- if (success_ptr) *success_ptr = true;
- return uval; // All characters were used, return the result
- }
- }
- if (success_ptr) *success_ptr = false;
- return fail_value;
-}
-
lldb::addr_t
Args::StringToAddress (const ExecutionContext *exe_ctx, const char *s, lldb::addr_t fail_value, Error *error_ptr)
{
@@ -878,7 +804,7 @@ Args::StringToAddress (const ExecutionContext *exe_ctx, const char *s, lldb::add
if (regex_match.GetMatchAtIndex(s, 3, str))
{
- offset = Args::StringToUInt64(str.c_str(), 0, 0, &success);
+ offset = StringConvert::ToUInt64(str.c_str(), 0, 0, &success);
if (success)
{
diff --git a/source/Interpreter/CommandHistory.cpp b/source/Interpreter/CommandHistory.cpp
index 26996a625642..bbe64b446acc 100644
--- a/source/Interpreter/CommandHistory.cpp
+++ b/source/Interpreter/CommandHistory.cpp
@@ -7,8 +7,10 @@
//
//===----------------------------------------------------------------------===//
+#include <inttypes.h>
+
#include "lldb/Interpreter/CommandHistory.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Host/StringConvert.h"
using namespace lldb;
using namespace lldb_private;
@@ -47,7 +49,7 @@ CommandHistory::FindString (const char* input_str) const
if (input_str[1] == '-')
{
bool success;
- size_t idx = Args::StringToUInt32 (input_str+2, 0, 0, &success);
+ size_t idx = StringConvert::ToUInt32 (input_str+2, 0, 0, &success);
if (!success)
return nullptr;
if (idx > m_history.size())
@@ -66,7 +68,7 @@ CommandHistory::FindString (const char* input_str) const
else
{
bool success;
- uint32_t idx = Args::StringToUInt32 (input_str+1, 0, 0, &success);
+ uint32_t idx = StringConvert::ToUInt32 (input_str+1, 0, 0, &success);
if (!success)
return nullptr;
if (idx >= m_history.size())
diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp
index 176a1fc9a3b0..6318b80a29ed 100644
--- a/source/Interpreter/CommandInterpreter.cpp
+++ b/source/Interpreter/CommandInterpreter.cpp
@@ -1170,17 +1170,25 @@ void
CommandInterpreter::GetHelp (CommandReturnObject &result,
uint32_t cmd_types)
{
+ const char * help_prologue = GetDebugger().GetIOHandlerHelpPrologue();
+ if (help_prologue != NULL)
+ {
+ OutputFormattedHelpText(result.GetOutputStream(), NULL, help_prologue);
+ }
+
CommandObject::CommandMap::const_iterator pos;
size_t max_len = FindLongestCommandWord (m_command_dict);
if ( (cmd_types & eCommandTypesBuiltin) == eCommandTypesBuiltin )
{
-
- result.AppendMessage("The following is a list of built-in, permanent debugger commands:");
+ result.AppendMessage("Debugger commands:");
result.AppendMessage("");
for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
{
+ if (!(cmd_types & eCommandTypesHidden) && (pos->first.compare(0, 1, "_") == 0))
+ continue;
+
OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(),
max_len);
}
@@ -1190,8 +1198,9 @@ CommandInterpreter::GetHelp (CommandReturnObject &result,
if (!m_alias_dict.empty() && ( (cmd_types & eCommandTypesAliases) == eCommandTypesAliases ))
{
- result.AppendMessage("The following is a list of your current command abbreviations "
- "(see 'help command alias' for more info):");
+ result.AppendMessageWithFormat("Current command abbreviations "
+ "(type '%shelp command alias' for more info):\n",
+ GetCommandPrefix());
result.AppendMessage("");
max_len = FindLongestCommandWord (m_alias_dict);
@@ -1212,7 +1221,7 @@ CommandInterpreter::GetHelp (CommandReturnObject &result,
if (!m_user_dict.empty() && ( (cmd_types & eCommandTypesUserDef) == eCommandTypesUserDef ))
{
- result.AppendMessage ("The following is a list of your current user-defined commands:");
+ result.AppendMessage ("Current user-defined commands:");
result.AppendMessage("");
max_len = FindLongestCommandWord (m_user_dict);
for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos)
@@ -1223,7 +1232,8 @@ CommandInterpreter::GetHelp (CommandReturnObject &result,
result.AppendMessage("");
}
- result.AppendMessage("For more information on any particular command, try 'help <command-name>'.");
+ result.AppendMessageWithFormat("For more information on any command, type '%shelp <command-name>'.\n",
+ GetCommandPrefix());
}
CommandObject *
@@ -2496,6 +2506,13 @@ CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result)
}
}
+const char *
+CommandInterpreter::GetCommandPrefix()
+{
+ const char * prefix = GetDebugger().GetIOHandlerCommandPrefix();
+ return prefix == NULL ? "" : prefix;
+}
+
PlatformSP
CommandInterpreter::GetPlatform (bool prefer_target_platform)
{
@@ -2887,84 +2904,74 @@ CommandInterpreter::SetSynchronous (bool value)
void
CommandInterpreter::OutputFormattedHelpText (Stream &strm,
- const char *word_text,
- const char *separator,
- const char *help_text,
- size_t max_word_len)
+ const char *prefix,
+ const char *help_text)
{
const uint32_t max_columns = m_debugger.GetTerminalWidth();
-
- int indent_size = max_word_len + strlen (separator) + 2;
-
- strm.IndentMore (indent_size);
-
- StreamString text_strm;
- text_strm.Printf ("%-*s %s %s", (int)max_word_len, word_text, separator, help_text);
-
- size_t len = text_strm.GetSize();
- const char *text = text_strm.GetData();
- if (text[len - 1] == '\n')
- {
- text_strm.EOL();
- len = text_strm.GetSize();
- }
-
- if (len < max_columns)
- {
- // Output it as a single line.
- strm.Printf ("%s", text);
- }
- else
- {
- // We need to break it up into multiple lines.
- bool first_line = true;
- int text_width;
- size_t start = 0;
- size_t end = start;
- const size_t final_end = strlen (text);
-
- while (end < final_end)
- {
- if (first_line)
- text_width = max_columns - 1;
- else
- text_width = max_columns - indent_size - 1;
-
- // Don't start the 'text' on a space, since we're already outputting the indentation.
- if (!first_line)
+ if (prefix == NULL)
+ prefix = "";
+
+ size_t prefix_width = strlen(prefix);
+ size_t line_width_max = max_columns - prefix_width;
+ const char *help_text_end = help_text + strlen(help_text);
+ const char *line_start = help_text;
+ if (line_width_max < 16)
+ line_width_max = help_text_end - help_text + prefix_width;
+
+ strm.IndentMore (prefix_width);
+ while (line_start < help_text_end)
+ {
+ // Break each line at the first newline or last space/tab before
+ // the maximum number of characters that fit on a line. Lines with no
+ // natural break are left unbroken to wrap.
+ const char *line_end = help_text_end;
+ const char *line_scan = line_start;
+ const char *line_scan_end = help_text_end;
+ while (line_scan < line_scan_end)
+ {
+ char next = *line_scan;
+ if (next == '\t' || next == ' ')
{
- while ((start < final_end) && (text[start] == ' '))
- start++;
+ line_end = line_scan;
+ line_scan_end = line_start + line_width_max;
}
-
- end = start + text_width;
- if (end > final_end)
- end = final_end;
- else
+ else if (next == '\n' || next == '\0')
{
- // If we're not at the end of the text, make sure we break the line on white space.
- while (end > start
- && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
- end--;
- assert (end > 0);
+ line_end = line_scan;
+ break;
}
-
- const size_t sub_len = end - start;
- if (start != 0)
- strm.EOL();
- if (!first_line)
- strm.Indent();
- else
- first_line = false;
- assert (start <= final_end);
- assert (start + sub_len <= final_end);
- if (sub_len > 0)
- strm.Write (text + start, sub_len);
- start = end + 1;
+ ++line_scan;
}
+
+ // Prefix the first line, indent subsequent lines to line up
+ if (line_start == help_text)
+ strm.Write (prefix, prefix_width);
+ else
+ strm.Indent();
+ strm.Write (line_start, line_end - line_start);
+ strm.EOL();
+
+ // When a line breaks at whitespace consume it before continuing
+ line_start = line_end;
+ char next = *line_start;
+ if (next == '\n')
+ ++line_start;
+ else while (next == ' ' || next == '\t')
+ next = *(++line_start);
}
- strm.EOL();
- strm.IndentLess(indent_size);
+ strm.IndentLess (prefix_width);
+}
+
+void
+CommandInterpreter::OutputFormattedHelpText (Stream &strm,
+ const char *word_text,
+ const char *separator,
+ const char *help_text,
+ size_t max_word_len)
+{
+ StreamString prefix_stream;
+ prefix_stream.Printf (" %-*s %s ", (int)max_word_len, word_text, separator);
+ OutputFormattedHelpText (strm, prefix_stream.GetData(), help_text);
}
void
@@ -3222,6 +3229,13 @@ CommandInterpreter::IOHandlerInterrupt (IOHandler &io_handler)
return true; // Don't do any updating when we are running
}
}
+
+ ScriptInterpreter *script_interpreter = GetScriptInterpreter (false);
+ if (script_interpreter)
+ {
+ if (script_interpreter->Interrupt())
+ return true;
+ }
return false;
}
diff --git a/source/Interpreter/CommandObjectRegexCommand.cpp b/source/Interpreter/CommandObjectRegexCommand.cpp
index efc7c33fa8f6..bde7f58b4cb0 100644
--- a/source/Interpreter/CommandObjectRegexCommand.cpp
+++ b/source/Interpreter/CommandObjectRegexCommand.cpp
@@ -111,7 +111,7 @@ CommandObjectRegexCommand::AddRegexCommand (const char *re_cstr, const char *com
{
m_entries.resize(m_entries.size() + 1);
// Only add the regular expression if it compiles
- if (m_entries.back().regex.Compile (re_cstr, REG_EXTENDED))
+ if (m_entries.back().regex.Compile (re_cstr))
{
m_entries.back().command.assign (command_cstr);
return true;
diff --git a/source/Interpreter/OptionGroupPlatform.cpp b/source/Interpreter/OptionGroupPlatform.cpp
index 7e5e1245a79f..6bb36552d06b 100644
--- a/source/Interpreter/OptionGroupPlatform.cpp
+++ b/source/Interpreter/OptionGroupPlatform.cpp
@@ -147,3 +147,38 @@ OptionGroupPlatform::SetOptionValue (CommandInterpreter &interpreter,
}
return error;
}
+
+bool
+OptionGroupPlatform::PlatformMatches(const lldb::PlatformSP &platform_sp) const
+{
+ if (platform_sp)
+ {
+ if (!m_platform_name.empty())
+ {
+ if (platform_sp->GetName() != ConstString(m_platform_name.c_str()))
+ return false;
+ }
+
+ if (m_sdk_build && m_sdk_build != platform_sp->GetSDKBuild())
+ return false;
+
+ if (m_sdk_sysroot && m_sdk_sysroot != platform_sp->GetSDKRootDirectory())
+ return false;
+
+ if (m_os_version_major != UINT32_MAX)
+ {
+ uint32_t major, minor, update;
+ if (platform_sp->GetOSVersion (major, minor, update))
+ {
+ if (m_os_version_major != major)
+ return false;
+ if (m_os_version_minor != minor)
+ return false;
+ if (m_os_version_update != update)
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+}
diff --git a/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/source/Interpreter/OptionGroupValueObjectDisplay.cpp
index b6c63fa44c40..72d7ff597ab2 100644
--- a/source/Interpreter/OptionGroupValueObjectDisplay.cpp
+++ b/source/Interpreter/OptionGroupValueObjectDisplay.cpp
@@ -16,6 +16,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/DataFormatters/ValueObjectPrinter.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Target/Target.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Utility/Utils.h"
@@ -89,13 +90,13 @@ OptionGroupValueObjectDisplay::SetOptionValue (CommandInterpreter &interpreter,
case 'A': ignore_cap = true; break;
case 'D':
- max_depth = Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success);
+ max_depth = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0, &success);
if (!success)
error.SetErrorStringWithFormat("invalid max depth '%s'", option_arg);
break;
case 'P':
- ptr_depth = Args::StringToUInt32 (option_arg, 0, 0, &success);
+ ptr_depth = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
if (!success)
error.SetErrorStringWithFormat("invalid pointer depth '%s'", option_arg);
break;
@@ -103,7 +104,7 @@ OptionGroupValueObjectDisplay::SetOptionValue (CommandInterpreter &interpreter,
case 'Y':
if (option_arg)
{
- no_summary_depth = Args::StringToUInt32 (option_arg, 0, 0, &success);
+ no_summary_depth = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
if (!success)
error.SetErrorStringWithFormat("invalid pointer depth '%s'", option_arg);
}
diff --git a/source/Interpreter/OptionValue.cpp b/source/Interpreter/OptionValue.cpp
index a08a6127db15..1e4ea23cc075 100644
--- a/source/Interpreter/OptionValue.cpp
+++ b/source/Interpreter/OptionValue.cpp
@@ -222,6 +222,22 @@ OptionValue::GetAsFormat () const
return nullptr;
}
+OptionValueFormatEntity *
+OptionValue::GetAsFormatEntity ()
+{
+ if (GetType () == OptionValue::eTypeFormatEntity)
+ return static_cast<OptionValueFormatEntity *>(this);
+ return nullptr;
+}
+
+const OptionValueFormatEntity *
+OptionValue::GetAsFormatEntity () const
+{
+ if (GetType () == OptionValue::eTypeFormatEntity)
+ return static_cast<const OptionValueFormatEntity *>(this);
+ return nullptr;
+}
+
OptionValuePathMappings *
OptionValue::GetAsPathMappings ()
{
@@ -452,6 +468,15 @@ OptionValue::SetFormatValue (lldb::Format new_value)
return false;
}
+const FormatEntity::Entry *
+OptionValue::GetFormatEntity () const
+{
+ const OptionValueFormatEntity *option_value = GetAsFormatEntity();
+ if (option_value)
+ return &option_value->GetCurrentValue();
+ return nullptr;
+}
+
const RegularExpression *
OptionValue::GetRegexValue () const
{
@@ -563,6 +588,7 @@ OptionValue::GetBuiltinTypeAsCString (Type t)
case eTypeFileSpec: return "file";
case eTypeFileSpecList: return "file-list";
case eTypeFormat: return "format";
+ case eTypeFormatEntity: return "format-string";
case eTypePathMap: return "path-map";
case eTypeProperties: return "properties";
case eTypeRegex: return "regex";
@@ -583,15 +609,16 @@ OptionValue::CreateValueFromCStringForTypeMask (const char *value_cstr, uint32_t
lldb::OptionValueSP value_sp;
switch (type_mask)
{
- case 1u << eTypeArch: value_sp.reset(new OptionValueArch()); break;
- case 1u << eTypeBoolean: value_sp.reset(new OptionValueBoolean(false)); break;
- case 1u << eTypeChar: value_sp.reset(new OptionValueChar('\0')); break;
- case 1u << eTypeFileSpec: value_sp.reset(new OptionValueFileSpec()); break;
- case 1u << eTypeFormat: value_sp.reset(new OptionValueFormat(eFormatInvalid)); break;
- case 1u << eTypeSInt64: value_sp.reset(new OptionValueSInt64()); break;
- case 1u << eTypeString: value_sp.reset(new OptionValueString()); break;
- case 1u << eTypeUInt64: value_sp.reset(new OptionValueUInt64()); break;
- case 1u << eTypeUUID: value_sp.reset(new OptionValueUUID()); break;
+ case 1u << eTypeArch: value_sp.reset(new OptionValueArch()); break;
+ case 1u << eTypeBoolean: value_sp.reset(new OptionValueBoolean(false)); break;
+ case 1u << eTypeChar: value_sp.reset(new OptionValueChar('\0')); break;
+ case 1u << eTypeFileSpec: value_sp.reset(new OptionValueFileSpec()); break;
+ case 1u << eTypeFormat: value_sp.reset(new OptionValueFormat(eFormatInvalid)); break;
+ case 1u << eTypeFormatEntity: value_sp.reset(new OptionValueFormatEntity(NULL)); break;
+ case 1u << eTypeSInt64: value_sp.reset(new OptionValueSInt64()); break;
+ case 1u << eTypeString: value_sp.reset(new OptionValueString()); break;
+ case 1u << eTypeUInt64: value_sp.reset(new OptionValueUInt64()); break;
+ case 1u << eTypeUUID: value_sp.reset(new OptionValueUUID()); break;
}
if (value_sp)
diff --git a/source/Interpreter/OptionValueArray.cpp b/source/Interpreter/OptionValueArray.cpp
index c0d48c1e7bd2..86d49c9ba3b4 100644
--- a/source/Interpreter/OptionValueArray.cpp
+++ b/source/Interpreter/OptionValueArray.cpp
@@ -14,6 +14,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Stream.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/Args.h"
using namespace lldb;
@@ -97,7 +98,7 @@ OptionValueArray::GetSubValue (const ExecutionContext *exe_ctx,
sub_value = end_bracket + 1;
std::string index_str (name+1, end_bracket);
const size_t array_count = m_values.size();
- int32_t idx = Args::StringToSInt32(index_str.c_str(), INT32_MAX, 0, nullptr);
+ int32_t idx = StringConvert::ToSInt32(index_str.c_str(), INT32_MAX, 0, nullptr);
if (idx != INT32_MAX)
{
;
@@ -177,7 +178,7 @@ OptionValueArray::SetArgs (const Args &args, VarSetOperationType op)
case eVarSetOperationInsertAfter:
if (argc > 1)
{
- uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
+ uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
const uint32_t count = GetSize();
if (idx > count)
{
@@ -225,7 +226,7 @@ OptionValueArray::SetArgs (const Args &args, VarSetOperationType op)
for (i=0; i<argc; ++i)
{
const size_t idx =
- Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
+ StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
if (idx >= size)
{
all_indexes_valid = false;
@@ -274,7 +275,7 @@ OptionValueArray::SetArgs (const Args &args, VarSetOperationType op)
case eVarSetOperationReplace:
if (argc > 1)
{
- uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
+ uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
const uint32_t count = GetSize();
if (idx > count)
{
diff --git a/source/Interpreter/OptionValueFileSpecLIst.cpp b/source/Interpreter/OptionValueFileSpecLIst.cpp
index 7150ad474643..0e696ca91db6 100644
--- a/source/Interpreter/OptionValueFileSpecLIst.cpp
+++ b/source/Interpreter/OptionValueFileSpecLIst.cpp
@@ -14,6 +14,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Stream.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/Args.h"
using namespace lldb;
@@ -57,7 +58,7 @@ OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperation
case eVarSetOperationReplace:
if (argc > 1)
{
- uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
+ uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
const uint32_t count = m_current_value.GetSize();
if (idx > count)
{
@@ -108,7 +109,7 @@ OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperation
case eVarSetOperationInsertAfter:
if (argc > 1)
{
- uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
+ uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
const uint32_t count = m_current_value.GetSize();
if (idx > count)
{
@@ -140,7 +141,7 @@ OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperation
size_t i;
for (i=0; all_indexes_valid && i<argc; ++i)
{
- const int idx = Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
+ const int idx = StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
if (idx == INT32_MAX)
all_indexes_valid = false;
else
diff --git a/source/Interpreter/OptionValueFormatEntity.cpp b/source/Interpreter/OptionValueFormatEntity.cpp
new file mode 100644
index 000000000000..fb8c682a03f8
--- /dev/null
+++ b/source/Interpreter/OptionValueFormatEntity.cpp
@@ -0,0 +1,124 @@
+//===-- OptionValueFormatEntity.cpp -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/Interpreter/OptionValueFormatEntity.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Module.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StringList.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+using namespace lldb;
+using namespace lldb_private;
+
+
+OptionValueFormatEntity::OptionValueFormatEntity (const char *default_format) :
+ OptionValue(),
+ m_current_format (),
+ m_default_format (),
+ m_current_entry (),
+ m_default_entry ()
+{
+ if (default_format && default_format[0])
+ {
+ llvm::StringRef default_format_str(default_format);
+ Error error = FormatEntity::Parse(default_format_str, m_default_entry);
+ if (error.Success())
+ {
+ m_default_format = default_format;
+ m_current_format = default_format;
+ m_current_entry = m_default_entry;
+ }
+ }
+}
+
+bool
+OptionValueFormatEntity::Clear ()
+{
+ m_current_entry = m_default_entry;
+ m_current_format = m_default_format;
+ m_value_was_set = false;
+ return true;
+}
+
+
+void
+OptionValueFormatEntity::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 (" = \"");
+ strm << m_current_format.c_str() << '"';
+ }
+}
+
+Error
+OptionValueFormatEntity::SetValueFromCString (const char *value_cstr,
+ VarSetOperationType op)
+{
+ Error error;
+ switch (op)
+ {
+ case eVarSetOperationClear:
+ Clear();
+ NotifyValueChanged();
+ break;
+
+ case eVarSetOperationReplace:
+ case eVarSetOperationAssign:
+ {
+ FormatEntity::Entry entry;
+ llvm::StringRef value_str(value_cstr);
+ error = FormatEntity::Parse(value_str, entry);
+ if (error.Success())
+ {
+ m_current_entry = std::move(entry);
+ m_current_format = value_cstr;
+ m_value_was_set = true;
+ NotifyValueChanged();
+ }
+ }
+ break;
+
+ case eVarSetOperationInsertBefore:
+ case eVarSetOperationInsertAfter:
+ case eVarSetOperationRemove:
+ case eVarSetOperationAppend:
+ case eVarSetOperationInvalid:
+ error = OptionValue::SetValueFromCString (value_cstr, op);
+ break;
+ }
+ return error;
+}
+
+lldb::OptionValueSP
+OptionValueFormatEntity::DeepCopy () const
+{
+ return OptionValueSP(new OptionValueFormatEntity(*this));
+}
+
+size_t
+OptionValueFormatEntity::AutoComplete (CommandInterpreter &interpreter,
+ const char *s,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches)
+{
+ return FormatEntity::AutoComplete (s, match_start_point, max_return_elements, word_complete, matches);
+}
+
diff --git a/source/Interpreter/OptionValuePathMappings.cpp b/source/Interpreter/OptionValuePathMappings.cpp
index 56f2ecf4f5fe..b1e714e97073 100644
--- a/source/Interpreter/OptionValuePathMappings.cpp
+++ b/source/Interpreter/OptionValuePathMappings.cpp
@@ -14,6 +14,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Stream.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/Args.h"
using namespace lldb;
@@ -50,7 +51,7 @@ OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperation
// Must be at least one index + 1 pair of paths, and the pair count must be even
if (argc >= 3 && (((argc - 1) & 1) == 0))
{
- uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
+ uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
const uint32_t count = m_path_mappings.GetSize();
if (idx > count)
{
@@ -108,7 +109,7 @@ OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperation
// Must be at least one index + 1 pair of paths, and the pair count must be even
if (argc >= 3 && (((argc - 1) & 1) == 0))
{
- uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
+ uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
const uint32_t count = m_path_mappings.GetSize();
if (idx > count)
{
@@ -141,7 +142,7 @@ OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperation
size_t i;
for (i=0; all_indexes_valid && i<argc; ++i)
{
- const int idx = Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
+ const int idx = StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
if (idx == INT32_MAX)
all_indexes_valid = false;
else
diff --git a/source/Interpreter/OptionValueProperties.cpp b/source/Interpreter/OptionValueProperties.cpp
index 6ec2aa569fa3..cf7abaa6ac25 100644
--- a/source/Interpreter/OptionValueProperties.cpp
+++ b/source/Interpreter/OptionValueProperties.cpp
@@ -421,6 +421,18 @@ OptionValueProperties::SetPropertyAtIndexAsEnumeration (const ExecutionContext *
return false;
}
+const FormatEntity::Entry *
+OptionValueProperties::GetPropertyAtIndexAsFormatEntity (const ExecutionContext *exe_ctx, uint32_t idx)
+{
+ const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
+ if (property)
+ {
+ OptionValue *value = property->GetValue().get();
+ if (value)
+ return value->GetFormatEntity();
+ }
+ return nullptr;
+}
OptionValueFileSpec *
OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
diff --git a/source/Interpreter/OptionValueRegex.cpp b/source/Interpreter/OptionValueRegex.cpp
index f51cf02edf56..fab462f0e704 100644
--- a/source/Interpreter/OptionValueRegex.cpp
+++ b/source/Interpreter/OptionValueRegex.cpp
@@ -62,7 +62,7 @@ OptionValueRegex::SetValueFromCString (const char *value_cstr,
case eVarSetOperationReplace:
case eVarSetOperationAssign:
- if (m_regex.Compile (value_cstr, m_regex.GetCompileFlags()))
+ if (m_regex.Compile (value_cstr))
{
m_value_was_set = true;
NotifyValueChanged();
@@ -84,5 +84,5 @@ OptionValueRegex::SetValueFromCString (const char *value_cstr,
lldb::OptionValueSP
OptionValueRegex::DeepCopy () const
{
- return OptionValueSP(new OptionValueRegex(m_regex.GetText(), m_regex.GetCompileFlags()));
+ return OptionValueSP(new OptionValueRegex(m_regex.GetText()));
}
diff --git a/source/Interpreter/OptionValueSInt64.cpp b/source/Interpreter/OptionValueSInt64.cpp
index 1827cc1d873f..c69172921a6d 100644
--- a/source/Interpreter/OptionValueSInt64.cpp
+++ b/source/Interpreter/OptionValueSInt64.cpp
@@ -14,7 +14,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Stream.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Host/StringConvert.h"
using namespace lldb;
using namespace lldb_private;
@@ -51,7 +51,7 @@ OptionValueSInt64::SetValueFromCString (const char *value_cstr, VarSetOperationT
case eVarSetOperationAssign:
{
bool success = false;
- int64_t value = Args::StringToSInt64 (value_cstr, 0, 0, &success);
+ int64_t value = StringConvert::ToSInt64 (value_cstr, 0, 0, &success);
if (success)
{
if (value >= m_min_value && value <= m_max_value)
diff --git a/source/Interpreter/OptionValueUInt64.cpp b/source/Interpreter/OptionValueUInt64.cpp
index 3e12c030255c..48de433d36c1 100644
--- a/source/Interpreter/OptionValueUInt64.cpp
+++ b/source/Interpreter/OptionValueUInt64.cpp
@@ -14,7 +14,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Stream.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Host/StringConvert.h"
using namespace lldb;
using namespace lldb_private;
@@ -58,7 +58,7 @@ OptionValueUInt64::SetValueFromCString (const char *value_cstr, VarSetOperationT
case eVarSetOperationAssign:
{
bool success = false;
- uint64_t value = Args::StringToUInt64 (value_cstr, 0, 0, &success);
+ uint64_t value = StringConvert::ToUInt64 (value_cstr, 0, 0, &success);
if (success)
{
m_value_was_set = true;
diff --git a/source/Interpreter/Property.cpp b/source/Interpreter/Property.cpp
index 7f7219fc0d50..5679ef8dd3ba 100644
--- a/source/Interpreter/Property.cpp
+++ b/source/Interpreter/Property.cpp
@@ -16,7 +16,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/UserSettingsController.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/OptionValues.h"
@@ -109,16 +109,21 @@ Property::Property (const PropertyDefinition &definition) :
// "definition.default_cstr_value" is NULL, otherwise interpret
// "definition.default_cstr_value" as a string value that represents the default
// value.
- {
- Format new_format = eFormatInvalid;
- if (definition.default_cstr_value)
- Args::StringToFormat (definition.default_cstr_value, new_format, nullptr);
- else
- new_format = (Format)definition.default_uint_value;
- m_value_sp.reset (new OptionValueFormat(new_format));
- }
+ {
+ Format new_format = eFormatInvalid;
+ if (definition.default_cstr_value)
+ Args::StringToFormat (definition.default_cstr_value, new_format, nullptr);
+ else
+ new_format = (Format)definition.default_uint_value;
+ m_value_sp.reset (new OptionValueFormat(new_format));
+ }
break;
+ case OptionValue::eTypeFormatEntity:
+ // "definition.default_cstr_value" as a string value that represents the default
+ m_value_sp.reset (new OptionValueFormatEntity(definition.default_cstr_value));
+ break;
+
case OptionValue::eTypePathMap:
// "definition.default_uint_value" tells us if notifications should occur for
// path mappings
@@ -129,7 +134,7 @@ Property::Property (const PropertyDefinition &definition) :
// "definition.default_uint_value" is used to the regular expression flags
// "definition.default_cstr_value" the default regular expression value
// value.
- m_value_sp.reset (new OptionValueRegex(definition.default_cstr_value, definition.default_uint_value));
+ m_value_sp.reset (new OptionValueRegex(definition.default_cstr_value));
break;
case OptionValue::eTypeSInt64:
@@ -137,7 +142,7 @@ Property::Property (const PropertyDefinition &definition) :
// "definition.default_cstr_value" is NULL, otherwise interpret
// "definition.default_cstr_value" as a string value that represents the default
// value.
- m_value_sp.reset (new OptionValueSInt64(definition.default_cstr_value ? Args::StringToSInt64 (definition.default_cstr_value) : definition.default_uint_value));
+ m_value_sp.reset (new OptionValueSInt64(definition.default_cstr_value ? StringConvert::ToSInt64 (definition.default_cstr_value) : definition.default_uint_value));
break;
case OptionValue::eTypeUInt64:
@@ -145,18 +150,18 @@ Property::Property (const PropertyDefinition &definition) :
// "definition.default_cstr_value" is NULL, otherwise interpret
// "definition.default_cstr_value" as a string value that represents the default
// value.
- m_value_sp.reset (new OptionValueUInt64(definition.default_cstr_value ? Args::StringToUInt64 (definition.default_cstr_value) : definition.default_uint_value));
+ m_value_sp.reset (new OptionValueUInt64(definition.default_cstr_value ? StringConvert::ToUInt64 (definition.default_cstr_value) : definition.default_uint_value));
break;
case OptionValue::eTypeUUID:
// "definition.default_uint_value" is not used for a OptionValue::eTypeUUID
// "definition.default_cstr_value" can contain a default UUID value
- {
- UUID uuid;
- if (definition.default_cstr_value)
- uuid.SetFromCString (definition.default_cstr_value);
- m_value_sp.reset (new OptionValueUUID(uuid));
- }
+ {
+ UUID uuid;
+ if (definition.default_cstr_value)
+ uuid.SetFromCString (definition.default_cstr_value);
+ m_value_sp.reset (new OptionValueUUID(uuid));
+ }
break;
case OptionValue::eTypeString:
diff --git a/source/Interpreter/ScriptInterpreterPython.cpp b/source/Interpreter/ScriptInterpreterPython.cpp
index ab151073f9e9..8155cbb189fe 100644
--- a/source/Interpreter/ScriptInterpreterPython.cpp
+++ b/source/Interpreter/ScriptInterpreterPython.cpp
@@ -103,13 +103,14 @@ ScriptInterpreterPython::Locker::DoAcquireLock()
m_GILState = PyGILState_Ensure();
if (log)
log->Printf("Ensured PyGILState. Previous state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : "");
-
+
// we need to save the thread state when we first start the command
// because we might decide to interrupt it while some action is taking
// place outside of Python (e.g. printing to screen, waiting for the network, ...)
// in that case, _PyThreadState_Current will be NULL - and we would be unable
// to set the asynchronous exception - not a desirable situation
m_python_interpreter->SetThreadState (_PyThreadState_Current);
+ m_python_interpreter->IncrementLockCount();
return true;
}
@@ -128,6 +129,7 @@ ScriptInterpreterPython::Locker::DoFreeLock()
if (log)
log->Printf("Releasing PyGILState. Returning to state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : "");
PyGILState_Release(m_GILState);
+ m_python_interpreter->DecrementLockCount();
return true;
}
@@ -166,6 +168,7 @@ ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interprete
m_session_is_active (false),
m_pty_slave_is_open (false),
m_valid_session (true),
+ m_lock_count (0),
m_command_thread_state (nullptr)
{
@@ -535,7 +538,7 @@ ScriptInterpreterPython::GetSysModuleDictionary ()
static std::string
GenerateUniqueName (const char* base_name_wanted,
uint32_t& functions_counter,
- void* name_token = nullptr)
+ const void* name_token = nullptr)
{
StreamString sstr;
@@ -817,24 +820,7 @@ public:
virtual bool
Interrupt ()
{
- Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
-
- PyThreadState* state = _PyThreadState_Current;
- if (!state)
- state = m_python->GetThreadState();
- if (state)
- {
- long tid = state->thread_id;
- _PyThreadState_Current = state;
- int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
- if (log)
- log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, tid = %ld, num_threads = %d, state = %p",
- tid, num_threads, static_cast<void *>(state));
- }
- else if (log)
- log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, state = NULL");
-
- return false;
+ return m_python->Interrupt();
}
virtual void
@@ -870,6 +856,31 @@ ScriptInterpreterPython::ExecuteInterpreterLoop ()
}
bool
+ScriptInterpreterPython::Interrupt()
+{
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
+
+ if (IsExecutingPython())
+ {
+ PyThreadState* state = _PyThreadState_Current;
+ if (!state)
+ state = GetThreadState();
+ if (state)
+ {
+ long tid = state->thread_id;
+ _PyThreadState_Current = state;
+ int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
+ if (log)
+ log->Printf("ScriptInterpreterPython::Interrupt() sending PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...", tid, num_threads);
+ return true;
+ }
+ }
+ if (log)
+ log->Printf("ScriptInterpreterPython::Interrupt() python code not running, can't interrupt");
+ return false;
+
+}
+bool
ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
ScriptInterpreter::ScriptReturnType return_type,
void *ret_value,
@@ -1243,7 +1254,7 @@ ScriptInterpreterPython::GenerateFunction(const char *signature, const StringLis
}
bool
-ScriptInterpreterPython::GenerateTypeScriptFunction (StringList &user_input, std::string& output, void* name_token)
+ScriptInterpreterPython::GenerateTypeScriptFunction (StringList &user_input, std::string& output, const void* name_token)
{
static uint32_t num_created_functions = 0;
user_input.RemoveBlankLines ();
@@ -1292,7 +1303,7 @@ ScriptInterpreterPython::GenerateScriptAliasFunction (StringList &user_input, st
bool
-ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, std::string &output, void* name_token)
+ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, std::string &output, const void* name_token)
{
static uint32_t num_created_classes = 0;
user_input.RemoveBlankLines ();
@@ -1795,7 +1806,7 @@ ScriptInterpreterPython::CreateSyntheticScriptedProvider (const char *class_name
}
bool
-ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, std::string& output, void* name_token)
+ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, std::string& output, const void* name_token)
{
StringList input;
input.SplitIntoLines(oneliner, strlen(oneliner));
@@ -1803,7 +1814,7 @@ ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, std::
}
bool
-ScriptInterpreterPython::GenerateTypeSynthClass (const char* oneliner, std::string& output, void* name_token)
+ScriptInterpreterPython::GenerateTypeSynthClass (const char* oneliner, std::string& output, const void* name_token)
{
StringList input;
input.SplitIntoLines(oneliner, strlen(oneliner));
diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
index 5073b13f09ab..42acba232de1 100644
--- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
+++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
@@ -334,11 +334,11 @@ ABIMacOSX_arm::GetArgumentValues (Thread &thread,
size_t bit_width = 0;
if (clang_type.IsIntegerType (is_signed))
{
- bit_width = clang_type.GetBitSize();
+ bit_width = clang_type.GetBitSize(nullptr);
}
else if (clang_type.IsPointerOrReferenceType ())
{
- bit_width = clang_type.GetBitSize();
+ bit_width = clang_type.GetBitSize(nullptr);
}
else
{
@@ -437,7 +437,7 @@ ABIMacOSX_arm::GetReturnValueObjectImpl (Thread &thread,
const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName("r0", 0);
if (clang_type.IsIntegerType (is_signed))
{
- size_t bit_width = clang_type.GetBitSize();
+ size_t bit_width = clang_type.GetBitSize(nullptr);
switch (bit_width)
{
diff --git a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
index 465257db31d8..c2ba165afb4a 100644
--- a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
+++ b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
@@ -322,11 +322,11 @@ ABIMacOSX_arm64::GetArgumentValues (Thread &thread, ValueList &values) const
size_t bit_width = 0;
if (value_type.IsIntegerType (is_signed))
{
- bit_width = value_type.GetBitSize();
+ bit_width = value_type.GetBitSize(nullptr);
}
else if (value_type.IsPointerOrReferenceType ())
{
- bit_width = value_type.GetBitSize();
+ bit_width = value_type.GetBitSize(nullptr);
}
else
{
@@ -709,7 +709,7 @@ LoadValueFromConsecutiveGPRRegisters (ExecutionContext &exe_ctx,
uint32_t &NSRN, // NSRN (see ABI documentation)
DataExtractor &data)
{
- const size_t byte_size = value_type.GetByteSize();
+ const size_t byte_size = value_type.GetByteSize(nullptr);
if (byte_size == 0)
return false;
@@ -728,7 +728,7 @@ LoadValueFromConsecutiveGPRRegisters (ExecutionContext &exe_ctx,
{
if (!base_type)
return false;
- const size_t base_byte_size = base_type.GetByteSize();
+ const size_t base_byte_size = base_type.GetByteSize(nullptr);
printf ("ClangASTContext::IsHomogeneousAggregate() => base_byte_size = %" PRIu64 "\n", (uint64_t) base_byte_size);
uint32_t data_offset = 0;
@@ -871,7 +871,7 @@ ABIMacOSX_arm64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_
if (!reg_ctx)
return return_valobj_sp;
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
const uint32_t type_flags = return_clang_type.GetTypeInfo (NULL);
if (type_flags & eTypeIsScalar ||
diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
index 9a1ea11cbae7..ee5b9298721b 100644
--- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
+++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
@@ -552,7 +552,7 @@ ABIMacOSX_i386::GetArgumentValues (Thread &thread,
if (clang_type.IsIntegerType (is_signed))
{
ReadIntegerArgument(value->GetScalar(),
- clang_type.GetBitSize(),
+ clang_type.GetBitSize(nullptr),
is_signed,
thread.GetProcess().get(),
current_stack_argument);
@@ -560,7 +560,7 @@ ABIMacOSX_i386::GetArgumentValues (Thread &thread,
else if (clang_type.IsPointerType())
{
ReadIntegerArgument(value->GetScalar(),
- clang_type.GetBitSize(),
+ clang_type.GetBitSize(nullptr),
false,
thread.GetProcess().get(),
current_stack_argument);
@@ -672,7 +672,7 @@ ABIMacOSX_i386::GetReturnValueObjectImpl (Thread &thread,
if (clang_type.IsIntegerType (is_signed))
{
- size_t bit_width = clang_type.GetBitSize();
+ size_t bit_width = clang_type.GetBitSize(nullptr);
unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
unsigned edx_id = reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
@@ -732,6 +732,10 @@ ABIMacOSX_i386::GetReturnValueObjectImpl (Thread &thread,
return return_valobj_sp;
}
+// This defines the CFA as esp+4
+// the saved pc is at CFA-4 (i.e. esp+0)
+// The saved esp is CFA+0
+
bool
ABIMacOSX_i386::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
{
@@ -745,12 +749,18 @@ ABIMacOSX_i386::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
row->SetCFARegister (sp_reg_num);
row->SetCFAOffset (4);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
+ row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
unwind_plan.AppendRow (row);
unwind_plan.SetSourceName ("i386 at-func-entry default");
unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
return true;
}
+// This defines the CFA as ebp+8
+// The saved pc is at CFA-4 (i.e. ebp+4)
+// The saved ebp is at CFA-8 (i.e. ebp+0)
+// The saved esp is CFA+0
+
bool
ABIMacOSX_i386::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
{
@@ -786,6 +796,11 @@ ABIMacOSX_i386::RegisterIsVolatile (const RegisterInfo *reg_info)
}
// v. http://developer.apple.com/library/mac/#documentation/developertools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html#//apple_ref/doc/uid/TP40002492-SW4
+//
+// This document ("OS X ABI Function Call Guide", chapter "IA-32 Function Calling Conventions")
+// says that the following registers on i386 are preserved aka non-volatile aka callee-saved:
+//
+// ebx, ebp, esi, edi, esp
bool
ABIMacOSX_i386::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
diff --git a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
index adb3313d1a30..741afebfcb8b 100644
--- a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
+++ b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
@@ -444,7 +444,7 @@ ABISysV_ppc::GetArgumentValues (Thread &thread,
if (clang_type.IsIntegerType (is_signed))
{
ReadIntegerArgument(value->GetScalar(),
- clang_type.GetBitSize(),
+ clang_type.GetBitSize(nullptr),
is_signed,
thread,
argument_register_ids,
@@ -454,7 +454,7 @@ ABISysV_ppc::GetArgumentValues (Thread &thread,
else if (clang_type.IsPointerType ())
{
ReadIntegerArgument(value->GetScalar(),
- clang_type.GetBitSize(),
+ clang_type.GetBitSize(nullptr),
false,
thread,
argument_register_ids,
@@ -524,7 +524,7 @@ ABISysV_ppc::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjec
error.SetErrorString ("We don't support returning complex values at present");
else
{
- size_t bit_width = clang_type.GetBitSize();
+ size_t bit_width = clang_type.GetBitSize(nullptr);
if (bit_width <= 64)
{
DataExtractor data;
@@ -588,7 +588,7 @@ ABISysV_ppc::GetReturnValueObjectSimple (Thread &thread,
{
// Extract the register context so we can read arguments from registers
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r3", 0), 0);
const bool is_signed = (type_flags & eTypeIsSigned) != 0;
switch (byte_size)
@@ -637,7 +637,7 @@ ABISysV_ppc::GetReturnValueObjectSimple (Thread &thread,
}
else
{
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
if (byte_size <= sizeof(long double))
{
const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
@@ -681,13 +681,11 @@ ABISysV_ppc::GetReturnValueObjectSimple (Thread &thread,
}
else if (type_flags & eTypeIsVector)
{
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
if (byte_size > 0)
{
- const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v0", 0);
- if (altivec_reg == NULL)
- altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
+ const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
if (altivec_reg)
{
if (byte_size <= altivec_reg->byte_size)
@@ -742,7 +740,7 @@ ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_clan
if (!reg_ctx_sp)
return return_valobj_sp;
- const size_t bit_width = return_clang_type.GetBitSize();
+ const size_t bit_width = return_clang_type.GetBitSize(nullptr);
if (return_clang_type.IsAggregateType())
{
Target *target = exe_ctx.GetTargetPtr();
@@ -784,7 +782,7 @@ ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_clan
uint32_t count;
ClangASTType field_clang_type = return_clang_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
- const size_t field_bit_width = field_clang_type.GetBitSize();
+ const size_t field_bit_width = field_clang_type.GetBitSize(nullptr);
// If there are any unaligned fields, this is stored in memory.
if (field_bit_offset % field_bit_width != 0)
diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
index 46f1e1023f0a..88c18fb6f202 100644
--- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
+++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
@@ -444,7 +444,7 @@ ABISysV_ppc64::GetArgumentValues (Thread &thread,
if (clang_type.IsIntegerType (is_signed))
{
ReadIntegerArgument(value->GetScalar(),
- clang_type.GetBitSize(),
+ clang_type.GetBitSize(nullptr),
is_signed,
thread,
argument_register_ids,
@@ -454,7 +454,7 @@ ABISysV_ppc64::GetArgumentValues (Thread &thread,
else if (clang_type.IsPointerType ())
{
ReadIntegerArgument(value->GetScalar(),
- clang_type.GetBitSize(),
+ clang_type.GetBitSize(nullptr),
false,
thread,
argument_register_ids,
@@ -524,7 +524,7 @@ ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObj
error.SetErrorString ("We don't support returning complex values at present");
else
{
- size_t bit_width = clang_type.GetBitSize();
+ size_t bit_width = clang_type.GetBitSize(nullptr);
if (bit_width <= 64)
{
DataExtractor data;
@@ -588,7 +588,7 @@ ABISysV_ppc64::GetReturnValueObjectSimple (Thread &thread,
{
// Extract the register context so we can read arguments from registers
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r3", 0), 0);
const bool is_signed = (type_flags & eTypeIsSigned) != 0;
switch (byte_size)
@@ -637,7 +637,7 @@ ABISysV_ppc64::GetReturnValueObjectSimple (Thread &thread,
}
else
{
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
if (byte_size <= sizeof(long double))
{
const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
@@ -681,13 +681,11 @@ ABISysV_ppc64::GetReturnValueObjectSimple (Thread &thread,
}
else if (type_flags & eTypeIsVector)
{
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
if (byte_size > 0)
{
- const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v0", 0);
- if (altivec_reg == NULL)
- altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
+ const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
if (altivec_reg)
{
if (byte_size <= altivec_reg->byte_size)
@@ -742,7 +740,7 @@ ABISysV_ppc64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_cl
if (!reg_ctx_sp)
return return_valobj_sp;
- const size_t bit_width = return_clang_type.GetBitSize();
+ const size_t bit_width = return_clang_type.GetBitSize(nullptr);
if (return_clang_type.IsAggregateType())
{
Target *target = exe_ctx.GetTargetPtr();
@@ -784,7 +782,7 @@ ABISysV_ppc64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_cl
uint32_t count;
ClangASTType field_clang_type = return_clang_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
- const size_t field_bit_width = field_clang_type.GetBitSize();
+ const size_t field_bit_width = field_clang_type.GetBitSize(nullptr);
// If there are any unaligned fields, this is stored in memory.
if (field_bit_offset % field_bit_width != 0)
diff --git a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
index 776e7fea67c7..71d99c8c65d2 100644
--- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
+++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
@@ -510,7 +510,7 @@ ABISysV_x86_64::GetArgumentValues (Thread &thread,
if (clang_type.IsIntegerType (is_signed))
{
ReadIntegerArgument(value->GetScalar(),
- clang_type.GetBitSize(),
+ clang_type.GetBitSize(nullptr),
is_signed,
thread,
argument_register_ids,
@@ -520,7 +520,7 @@ ABISysV_x86_64::GetArgumentValues (Thread &thread,
else if (clang_type.IsPointerType ())
{
ReadIntegerArgument(value->GetScalar(),
- clang_type.GetBitSize(),
+ clang_type.GetBitSize(nullptr),
false,
thread,
argument_register_ids,
@@ -590,7 +590,7 @@ ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueOb
error.SetErrorString ("We don't support returning complex values at present");
else
{
- size_t bit_width = clang_type.GetBitSize();
+ size_t bit_width = clang_type.GetBitSize(nullptr);
if (bit_width <= 64)
{
const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
@@ -658,7 +658,7 @@ ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
{
// Extract the register context so we can read arguments from registers
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("rax", 0), 0);
const bool is_signed = (type_flags & eTypeIsSigned) != 0;
switch (byte_size)
@@ -707,7 +707,7 @@ ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
}
else
{
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
if (byte_size <= sizeof(long double))
{
const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
@@ -755,7 +755,7 @@ ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
}
else if (type_flags & eTypeIsVector)
{
- const size_t byte_size = return_clang_type.GetByteSize();
+ const size_t byte_size = return_clang_type.GetByteSize(nullptr);
if (byte_size > 0)
{
@@ -821,7 +821,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_c
if (!reg_ctx_sp)
return return_valobj_sp;
- const size_t bit_width = return_clang_type.GetBitSize();
+ const size_t bit_width = return_clang_type.GetBitSize(nullptr);
if (return_clang_type.IsAggregateType())
{
Target *target = exe_ctx.GetTargetPtr();
@@ -869,7 +869,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_c
uint32_t count;
ClangASTType field_clang_type = return_clang_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
- const size_t field_bit_width = field_clang_type.GetBitSize();
+ const size_t field_bit_width = field_clang_type.GetBitSize(nullptr);
// If there are any unaligned fields, this is stored in memory.
if (field_bit_offset % field_bit_width != 0)
@@ -1070,6 +1070,10 @@ ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_c
return return_valobj_sp;
}
+// This defines the CFA as rsp+8
+// the saved pc is at CFA-8 (i.e. rsp+0)
+// The saved rsp is CFA+0
+
bool
ABISysV_x86_64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
{
@@ -1083,12 +1087,18 @@ ABISysV_x86_64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
row->SetCFARegister (sp_reg_num);
row->SetCFAOffset (8);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
+ row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
unwind_plan.AppendRow (row);
unwind_plan.SetSourceName ("x86_64 at-func-entry default");
unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
return true;
}
+// This defines the CFA as rbp+16
+// The saved pc is at CFA-8 (i.e. rbp+8)
+// The saved rbp is at CFA-16 (i.e. rbp+0)
+// The saved rsp is CFA+0
+
bool
ABISysV_x86_64::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
{
@@ -1132,6 +1142,7 @@ ABISysV_x86_64::RegisterIsVolatile (const RegisterInfo *reg_info)
// (this doc is also commonly referred to as the x86-64/AMD64 psABI)
// Edited by Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell
// current version is 0.99.6 released 2012-07-02 at http://refspecs.linuxfoundation.org/elf/x86-64-abi-0.99.pdf
+// It's being revised & updated at https://github.com/hjl-tools/x86-psABI/
bool
ABISysV_x86_64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
index 97ddbef0e307..2f9012222c02 100644
--- a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
+++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
@@ -371,7 +371,7 @@ public:
}
}
- static RegularExpression s_regex("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?", REG_EXTENDED);
+ static RegularExpression s_regex("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?");
RegularExpression::Match matches(3);
@@ -457,7 +457,7 @@ DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, uns
std::unique_ptr<llvm::MCSymbolizer> symbolizer_up(curr_target->createMCSymbolizer(triple, NULL,
DisassemblerLLVMC::SymbolLookupCallback,
(void *) &owner,
- m_context_ap.get(), RelInfo.release()));
+ m_context_ap.get(), std::move(RelInfo)));
m_disasm_ap->setSymbolizer(std::move(symbolizer_up));
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index d8279e44e14a..a504e801daac 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -19,6 +19,8 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "llvm/Support/Path.h"
+
#include "DYLDRendezvous.h"
using namespace lldb;
@@ -238,9 +240,7 @@ DYLDRendezvous::UpdateSOEntriesForAddition()
return false;
// Only add shared libraries and not the executable.
- // On Linux this is indicated by an empty path in the entry.
- // On FreeBSD it is the name of the executable.
- if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
+ if (SOEntryIsMainExecutable(entry))
continue;
pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
@@ -277,6 +277,28 @@ DYLDRendezvous::UpdateSOEntriesForDeletion()
}
bool
+DYLDRendezvous::SOEntryIsMainExecutable(const SOEntry &entry)
+{
+ // On Linux the executable is indicated by an empty path in the entry. On
+ // FreeBSD it is the full path to the executable. On Android, it is the
+ // basename of the executable.
+
+ auto triple = m_process->GetTarget().GetArchitecture().GetTriple();
+ auto os_type = triple.getOS();
+ auto env_type = triple.getEnvironment();
+
+ switch (os_type) {
+ case llvm::Triple::FreeBSD:
+ return ::strcmp(entry.path.c_str(), m_exe_path) == 0;
+ case llvm::Triple::Linux:
+ return entry.path.empty() || (env_type == llvm::Triple::Android &&
+ llvm::sys::path::filename(m_exe_path) == entry.path);
+ default:
+ return false;
+ }
+}
+
+bool
DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list)
{
SOEntry entry;
@@ -290,9 +312,7 @@ DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list)
return false;
// Only add shared libraries and not the executable.
- // On Linux this is indicated by an empty path in the entry.
- // On FreeBSD it is the name of the executable.
- if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
+ if (SOEntryIsMainExecutable(entry))
continue;
entry_list.push_back(entry);
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
index ca0089317998..51fcd9b7d397 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
@@ -247,6 +247,9 @@ protected:
bool
UpdateSOEntriesForDeletion();
+ bool
+ SOEntryIsMainExecutable(const SOEntry &entry);
+
/// Reads the current list of shared objects according to the link map
/// supplied by the runtime linker.
bool
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index 6b0b6f5cc8b8..fdef1026f3c6 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -542,6 +542,9 @@ DynamicLoaderPOSIXDYLD::ComputeLoadOffset()
return LLDB_INVALID_ADDRESS;
ObjectFile *exe = module->GetObjectFile();
+ if (!exe)
+ return LLDB_INVALID_ADDRESS;
+
Address file_entry = exe->GetEntryPointAddress();
if (!file_entry.IsValid())
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index a6c74f3f1fc4..50537eb119f2 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -291,7 +291,8 @@ ItaniumABILanguageRuntime::CreateInstance (Process *process, lldb::LanguageType
// the Itanium ABI.
if (language == eLanguageTypeC_plus_plus ||
language == eLanguageTypeC_plus_plus_03 ||
- language == eLanguageTypeC_plus_plus_11)
+ language == eLanguageTypeC_plus_plus_11 ||
+ language == eLanguageTypeC_plus_plus_14)
return new ItaniumABILanguageRuntime (process);
else
return NULL;
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index b1be0f5b1fe1..5b72728c2b48 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -288,82 +288,6 @@ PlatformPOSIX::PutFile (const lldb_private::FileSpec& source,
}
// if we are still here rsync has failed - let's try the slow way before giving up
}
-
- if (log)
- log->Printf ("PlatformPOSIX::PutFile(src='%s', dst='%s', uid=%u, gid=%u)",
- source.GetPath().c_str(),
- destination.GetPath().c_str(),
- uid,
- gid); // REMOVE THIS PRINTF PRIOR TO CHECKIN
- // open
- // read, write, read, write, ...
- // close
- // chown uid:gid dst
- if (log)
- log->Printf("[PutFile] Using block by block transfer....\n");
-
- uint32_t source_open_options = File::eOpenOptionRead;
- if (source.GetFileType() == FileSpec::eFileTypeSymbolicLink)
- source_open_options |= File::eOpenoptionDontFollowSymlinks;
-
- File source_file(source, source_open_options, lldb::eFilePermissionsUserRW);
- Error error;
- uint32_t permissions = source_file.GetPermissions(error);
- if (permissions == 0)
- permissions = lldb::eFilePermissionsFileDefault;
-
- if (!source_file.IsValid())
- return Error("unable to open source file");
- lldb::user_id_t dest_file = OpenFile (destination,
- File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate,
- permissions,
- error);
- if (log)
- log->Printf ("dest_file = %" PRIu64 "\n", dest_file);
- if (error.Fail())
- return error;
- if (dest_file == UINT64_MAX)
- return Error("unable to open target file");
- lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0));
- uint64_t offset = 0;
- while (error.Success())
- {
- size_t bytes_read = buffer_sp->GetByteSize();
- error = source_file.Read(buffer_sp->GetBytes(), bytes_read);
- if (bytes_read)
- {
- const uint64_t bytes_written = WriteFile(dest_file, offset, buffer_sp->GetBytes(), bytes_read, error);
- offset += bytes_written;
- if (bytes_written != bytes_read)
- {
- // We didn't write the correct numbe of bytes, so adjust
- // the file position in the source file we are reading from...
- source_file.SeekFromStart(offset);
- }
- }
- else
- break;
- }
- CloseFile(dest_file, error);
- if (uid == UINT32_MAX && gid == UINT32_MAX)
- return error;
- // This is remopve, don't chown a local file...
-// std::string dst_path (destination.GetPath());
-// if (chown_file(this,dst_path.c_str(),uid,gid) != 0)
-// return Error("unable to perform chown");
-
-
- uint64_t src_md5[2];
- uint64_t dst_md5[2];
-
- if (FileSystem::CalculateMD5 (source, src_md5[0], src_md5[1]) && CalculateMD5 (destination, dst_md5[0], dst_md5[1]))
- {
- if (src_md5[0] != dst_md5[0] || src_md5[1] != dst_md5[1])
- {
- error.SetErrorString("md5 checksum of installed file doesn't match, installation failed");
- }
- }
- return error;
}
return Platform::PutFile(source,destination,uid,gid);
}
@@ -841,8 +765,12 @@ PlatformPOSIX::Attach (ProcessAttachInfo &attach_info,
// Set UnixSignals appropriately.
process_sp->SetUnixSignals (Host::GetUnixSignals ());
- ListenerSP listener_sp (new Listener("lldb.PlatformPOSIX.attach.hijack"));
- attach_info.SetHijackListener(listener_sp);
+ auto listener_sp = attach_info.GetHijackListener();
+ if (listener_sp == nullptr)
+ {
+ listener_sp.reset(new Listener("lldb.PlatformPOSIX.attach.hijack"));
+ attach_info.SetHijackListener(listener_sp);
+ }
process_sp->HijackProcessEvents(listener_sp.get());
error = process_sp->Attach (attach_info);
}
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 43eae4d906ec..ec2084aaf98c 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -30,6 +30,8 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "Utility/UriParser.h"
+
using namespace lldb;
using namespace lldb_private;
@@ -105,12 +107,76 @@ PlatformRemoteGDBServer::ResolveExecutable (const ModuleSpec &module_spec,
lldb::ModuleSP &exe_module_sp,
const FileSpecList *module_search_paths_ptr)
{
+ // copied from PlatformRemoteiOS
+
Error error;
- //error.SetErrorString ("PlatformRemoteGDBServer::ResolveExecutable() is unimplemented");
- if (m_gdb_client.GetFileExists(module_spec.GetFileSpec()))
- return error;
- // TODO: get the remote end to somehow resolve this file
- error.SetErrorString("file not found on remote end");
+ // Nothing special to do here, just use the actual file and architecture
+
+ ModuleSpec resolved_module_spec(module_spec);
+
+ // Resolve any executable within an apk on Android?
+ //Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
+
+ if (resolved_module_spec.GetFileSpec().Exists())
+ {
+ if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid())
+ {
+ error = ModuleList::GetSharedModule (resolved_module_spec,
+ exe_module_sp,
+ NULL,
+ NULL,
+ NULL);
+
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ return error;
+ exe_module_sp.reset();
+ }
+ // No valid architecture was specified or the exact arch wasn't
+ // found so ask the platform for the architectures that we should be
+ // using (in the correct order) and see if we can find a match that way
+ StreamString arch_names;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
+ {
+ error = ModuleList::GetSharedModule (resolved_module_spec,
+ exe_module_sp,
+ NULL,
+ NULL,
+ NULL);
+ // Did we find an executable using one of the
+ if (error.Success())
+ {
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ break;
+ else
+ error.SetErrorToGenericError();
+ }
+
+ if (idx > 0)
+ arch_names.PutCString (", ");
+ arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
+ }
+
+ if (error.Fail() || !exe_module_sp)
+ {
+ if (resolved_module_spec.GetFileSpec().Readable())
+ {
+ error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
+ resolved_module_spec.GetFileSpec().GetPath().c_str(),
+ GetPluginName().GetCString(),
+ arch_names.GetString().c_str());
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
+ }
+ }
+ else
+ {
+ error.SetErrorStringWithFormat ("'%s' does not exist",
+ resolved_module_spec.GetFileSpec().GetPath().c_str());
+ }
+
return error;
}
@@ -146,6 +212,15 @@ PlatformRemoteGDBServer::~PlatformRemoteGDBServer()
bool
PlatformRemoteGDBServer::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
{
+ ArchSpec remote_arch = m_gdb_client.GetSystemArchitecture();
+
+ // TODO: 64 bit systems should also advertize support for 32 bit arch
+ // unknown CPU, we just support the one arch
+ if (idx == 0)
+ {
+ arch = remote_arch;
+ return true;
+ }
return false;
}
@@ -252,6 +327,17 @@ PlatformRemoteGDBServer::ConnectRemote (Args& args)
{
const char *url = args.GetArgumentAtIndex(0);
m_gdb_client.SetConnection (new ConnectionFileDescriptor());
+
+ // we're going to reuse the hostname when we connect to the debugserver
+ std::string scheme;
+ int port;
+ std::string path;
+ if ( !UriParser::Parse(url, scheme, m_platform_hostname, port, path) )
+ {
+ error.SetErrorString("invalid uri");
+ return error;
+ }
+
const ConnectionStatus status = m_gdb_client.Connect(url, &error);
if (status == eConnectionStatusSuccess)
{
@@ -344,14 +430,30 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
Error error;
- lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
if (log)
log->Printf ("PlatformRemoteGDBServer::%s() called", __FUNCTION__);
- m_gdb_client.SetSTDIN ("/dev/null");
- m_gdb_client.SetSTDOUT ("/dev/null");
- m_gdb_client.SetSTDERR ("/dev/null");
+ auto num_file_actions = launch_info.GetNumFileActions ();
+ for (decltype(num_file_actions) i = 0; i < num_file_actions; ++i)
+ {
+ const auto file_action = launch_info.GetFileActionAtIndex (i);
+ if (file_action->GetAction () != FileAction::eFileActionOpen)
+ continue;
+ switch(file_action->GetFD())
+ {
+ case STDIN_FILENO:
+ m_gdb_client.SetSTDIN (file_action->GetPath());
+ break;
+ case STDOUT_FILENO:
+ m_gdb_client.SetSTDOUT (file_action->GetPath());
+ break;
+ case STDERR_FILENO:
+ m_gdb_client.SetSTDERR (file_action->GetPath());
+ break;
+ }
+ }
+
m_gdb_client.SetDisableASLR (launch_info.GetFlags().Test (eLaunchFlagDisableASLR));
m_gdb_client.SetDetachOnError (launch_info.GetFlags().Test (eLaunchFlagDetachOnError));
@@ -389,7 +491,7 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
std::string error_str;
if (m_gdb_client.GetLaunchSuccess (error_str))
{
- pid = m_gdb_client.GetCurrentProcessID ();
+ const auto pid = m_gdb_client.GetCurrentProcessID (false);
if (pid != LLDB_INVALID_PROCESS_ID)
{
launch_info.SetProcessID (pid);
@@ -400,7 +502,7 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
{
if (log)
log->Printf ("PlatformRemoteGDBServer::%s() launch succeeded but we didn't get a valid process id back!", __FUNCTION__);
- // FIXME isn't this an error condition? Do we need to set an error here? Check with Greg.
+ error.SetErrorString ("failed to get PID");
}
}
else
@@ -417,6 +519,14 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
return error;
}
+Error
+PlatformRemoteGDBServer::KillProcess (const lldb::pid_t pid)
+{
+ if (!m_gdb_client.KillSpawnedProcess(pid))
+ return Error("failed to kill remote spawned process");
+ return Error();
+}
+
lldb::ProcessSP
PlatformRemoteGDBServer::DebugProcess (lldb_private::ProcessLaunchInfo &launch_info,
lldb_private::Debugger &debugger,
@@ -483,7 +593,7 @@ PlatformRemoteGDBServer::DebugProcess (lldb_private::ProcessLaunchInfo &launch_i
const int connect_url_len = ::snprintf (connect_url,
sizeof(connect_url),
"connect://%s:%u",
- override_hostname ? override_hostname : GetHostname (),
+ override_hostname ? override_hostname : m_platform_hostname.c_str(),
port + port_offset);
assert (connect_url_len < (int)sizeof(connect_url));
error = process_sp->ConnectRemote (NULL, connect_url);
@@ -576,13 +686,19 @@ PlatformRemoteGDBServer::Attach (lldb_private::ProcessAttachInfo &attach_info,
const int connect_url_len = ::snprintf (connect_url,
sizeof(connect_url),
"connect://%s:%u",
- override_hostname ? override_hostname : GetHostname (),
+ override_hostname ? override_hostname : m_platform_hostname.c_str(),
port + port_offset);
assert (connect_url_len < (int)sizeof(connect_url));
- error = process_sp->ConnectRemote (NULL, connect_url);
+ error = process_sp->ConnectRemote(nullptr, connect_url);
if (error.Success())
+ {
+ auto listener = attach_info.GetHijackListener();
+ if (listener != nullptr)
+ process_sp->HijackProcessEvents(listener.get());
error = process_sp->Attach(attach_info);
- else if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
+ }
+
+ if (error.Fail() && debugserver_pid != LLDB_INVALID_PROCESS_ID)
{
m_gdb_client.KillSpawnedProcess(debugserver_pid);
}
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index 90b16b8b8fa9..a928c4695f79 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -86,7 +86,10 @@ public:
virtual lldb_private::Error
LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info);
-
+
+ virtual lldb_private::Error
+ KillProcess (const lldb::pid_t pid);
+
virtual lldb::ProcessSP
DebugProcess (lldb_private::ProcessLaunchInfo &launch_info,
lldb_private::Debugger &debugger,
@@ -212,6 +215,7 @@ public:
protected:
GDBRemoteCommunicationClient m_gdb_client;
std::string m_platform_description; // After we connect we can get a more complete description of what we are connected to
+ std::string m_platform_hostname;
private:
DISALLOW_COPY_AND_ASSIGN (PlatformRemoteGDBServer);
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
index 84e35ba22644..b33f83303971 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -30,7 +30,7 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/PseudoTerminal.h"
-
+#include "Plugins/Process/POSIX/CrashReason.h"
#include "POSIXThread.h"
#include "ProcessFreeBSD.h"
#include "ProcessPOSIXLog.h"
@@ -994,6 +994,11 @@ ProcessMonitor::Launch(LaunchArgs *args)
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.CloseSlaveFileDescriptor();
+
// Do not inherit setgid powers.
if (setgid(getgid()) != 0)
exit(eSetGidFailed);
@@ -1306,27 +1311,14 @@ ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
if (log)
log->Printf ("ProcessMonitor::%s() received signal %s", __FUNCTION__, monitor->m_process->GetUnixSignals().GetSignalAsCString (signo));
- if (signo == SIGSEGV) {
- lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
- ProcessMessage::CrashReason reason = GetCrashReasonForSIGSEGV(info);
- return ProcessMessage::Crash(tid, reason, signo, fault_addr);
- }
-
- if (signo == SIGILL) {
- lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
- ProcessMessage::CrashReason reason = GetCrashReasonForSIGILL(info);
- return ProcessMessage::Crash(tid, reason, signo, fault_addr);
- }
-
- if (signo == SIGFPE) {
- lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
- ProcessMessage::CrashReason reason = GetCrashReasonForSIGFPE(info);
- return ProcessMessage::Crash(tid, reason, signo, fault_addr);
- }
-
- if (signo == SIGBUS) {
+ switch (signo)
+ {
+ case SIGSEGV:
+ case SIGILL:
+ case SIGFPE:
+ case SIGBUS:
lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
- ProcessMessage::CrashReason reason = GetCrashReasonForSIGBUS(info);
+ const auto reason = GetCrashReason(*info);
return ProcessMessage::Crash(tid, reason, signo, fault_addr);
}
@@ -1335,141 +1327,6 @@ ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
return ProcessMessage::Signal(tid, signo);
}
-ProcessMessage::CrashReason
-ProcessMonitor::GetCrashReasonForSIGSEGV(const siginfo_t *info)
-{
- ProcessMessage::CrashReason reason;
- assert(info->si_signo == SIGSEGV);
-
- reason = ProcessMessage::eInvalidCrashReason;
-
- switch (info->si_code)
- {
- default:
- assert(false && "unexpected si_code for SIGSEGV");
- break;
- case SEGV_MAPERR:
- reason = ProcessMessage::eInvalidAddress;
- break;
- case SEGV_ACCERR:
- reason = ProcessMessage::ePrivilegedAddress;
- break;
- }
-
- return reason;
-}
-
-ProcessMessage::CrashReason
-ProcessMonitor::GetCrashReasonForSIGILL(const siginfo_t *info)
-{
- ProcessMessage::CrashReason reason;
- assert(info->si_signo == SIGILL);
-
- reason = ProcessMessage::eInvalidCrashReason;
-
- switch (info->si_code)
- {
- default:
- assert(false && "unexpected si_code for SIGILL");
- break;
- case ILL_ILLOPC:
- reason = ProcessMessage::eIllegalOpcode;
- break;
- case ILL_ILLOPN:
- reason = ProcessMessage::eIllegalOperand;
- break;
- case ILL_ILLADR:
- reason = ProcessMessage::eIllegalAddressingMode;
- break;
- case ILL_ILLTRP:
- reason = ProcessMessage::eIllegalTrap;
- break;
- case ILL_PRVOPC:
- reason = ProcessMessage::ePrivilegedOpcode;
- break;
- case ILL_PRVREG:
- reason = ProcessMessage::ePrivilegedRegister;
- break;
- case ILL_COPROC:
- reason = ProcessMessage::eCoprocessorError;
- break;
- case ILL_BADSTK:
- reason = ProcessMessage::eInternalStackError;
- break;
- }
-
- return reason;
-}
-
-ProcessMessage::CrashReason
-ProcessMonitor::GetCrashReasonForSIGFPE(const siginfo_t *info)
-{
- ProcessMessage::CrashReason reason;
- assert(info->si_signo == SIGFPE);
-
- reason = ProcessMessage::eInvalidCrashReason;
-
- switch (info->si_code)
- {
- default:
- assert(false && "unexpected si_code for SIGFPE");
- break;
- case FPE_INTDIV:
- reason = ProcessMessage::eIntegerDivideByZero;
- break;
- case FPE_INTOVF:
- reason = ProcessMessage::eIntegerOverflow;
- break;
- case FPE_FLTDIV:
- reason = ProcessMessage::eFloatDivideByZero;
- break;
- case FPE_FLTOVF:
- reason = ProcessMessage::eFloatOverflow;
- break;
- case FPE_FLTUND:
- reason = ProcessMessage::eFloatUnderflow;
- break;
- case FPE_FLTRES:
- reason = ProcessMessage::eFloatInexactResult;
- break;
- case FPE_FLTINV:
- reason = ProcessMessage::eFloatInvalidOperation;
- break;
- case FPE_FLTSUB:
- reason = ProcessMessage::eFloatSubscriptRange;
- break;
- }
-
- return reason;
-}
-
-ProcessMessage::CrashReason
-ProcessMonitor::GetCrashReasonForSIGBUS(const siginfo_t *info)
-{
- ProcessMessage::CrashReason reason;
- assert(info->si_signo == SIGBUS);
-
- reason = ProcessMessage::eInvalidCrashReason;
-
- switch (info->si_code)
- {
- default:
- assert(false && "unexpected si_code for SIGBUS");
- break;
- case BUS_ADRALN:
- reason = ProcessMessage::eIllegalAlignment;
- break;
- case BUS_ADRERR:
- reason = ProcessMessage::eIllegalAddress;
- break;
- case BUS_OBJERR:
- reason = ProcessMessage::eHardwareError;
- break;
- }
-
- return reason;
-}
-
void
ProcessMonitor::ServeOperation(OperationArgs *args)
{
@@ -1706,7 +1563,10 @@ ProcessMonitor::DupDescriptor(const char *path, int fd, int flags)
if (target_fd == -1)
return false;
- return (dup2(target_fd, fd) == -1) ? false : true;
+ if (dup2(target_fd, fd) == -1)
+ return false;
+
+ return (close(target_fd) == -1) ? false : true;
}
void
@@ -1727,11 +1587,10 @@ ProcessMonitor::StopMonitor()
StopOpThread();
sem_destroy(&m_operation_pending);
sem_destroy(&m_operation_done);
-
- // Note: ProcessPOSIX passes the m_terminal_fd file descriptor to
- // Process::SetSTDIOFileDescriptor, which in turn transfers ownership of
- // the descriptor to a ConnectionFileDescriptor object. Consequently
- // even though still has the file descriptor, we shouldn't close it here.
+ 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,
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
index 935fd85ed37a..4ae963c89a2f 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.h
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
@@ -79,7 +79,8 @@ public:
/// 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).
+ /// 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.
@@ -311,18 +312,6 @@ private:
MonitorSignal(ProcessMonitor *monitor,
const siginfo_t *info, lldb::pid_t pid);
- static ProcessMessage::CrashReason
- GetCrashReasonForSIGSEGV(const siginfo_t *info);
-
- static ProcessMessage::CrashReason
- GetCrashReasonForSIGILL(const siginfo_t *info);
-
- static ProcessMessage::CrashReason
- GetCrashReasonForSIGFPE(const siginfo_t *info);
-
- static ProcessMessage::CrashReason
- GetCrashReasonForSIGBUS(const siginfo_t *info);
-
void
DoOperation(Operation *op);
diff --git a/source/Plugins/Process/POSIX/CrashReason.cpp b/source/Plugins/Process/POSIX/CrashReason.cpp
new file mode 100644
index 000000000000..4dd91a6f1de8
--- /dev/null
+++ b/source/Plugins/Process/POSIX/CrashReason.cpp
@@ -0,0 +1,315 @@
+//===-- CrashReason.cpp -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CrashReason.h"
+
+#include <sstream>
+
+namespace {
+
+void
+AppendFaultAddr (std::string& str, lldb::addr_t addr)
+{
+ std::stringstream ss;
+ ss << " (fault address: 0x" << std::hex << addr << ")";
+ str += ss.str();
+}
+
+CrashReason
+GetCrashReasonForSIGSEGV(const siginfo_t& info)
+{
+ assert(info.si_signo == SIGSEGV);
+
+ switch (info.si_code)
+ {
+ case SI_KERNEL:
+ // Linux will occasionally send spurious SI_KERNEL codes.
+ // (this is poorly documented in sigaction)
+ // One way to get this is via unaligned SIMD loads.
+ return CrashReason::eInvalidAddress; // for lack of anything better
+ case SEGV_MAPERR:
+ return CrashReason::eInvalidAddress;
+ case SEGV_ACCERR:
+ return CrashReason::ePrivilegedAddress;
+ }
+
+ assert(false && "unexpected si_code for SIGSEGV");
+ return CrashReason::eInvalidCrashReason;
+}
+
+CrashReason
+GetCrashReasonForSIGILL(const siginfo_t& info)
+{
+ assert(info.si_signo == SIGILL);
+
+ switch (info.si_code)
+ {
+ case ILL_ILLOPC:
+ return CrashReason::eIllegalOpcode;
+ case ILL_ILLOPN:
+ return CrashReason::eIllegalOperand;
+ case ILL_ILLADR:
+ return CrashReason::eIllegalAddressingMode;
+ case ILL_ILLTRP:
+ return CrashReason::eIllegalTrap;
+ case ILL_PRVOPC:
+ return CrashReason::ePrivilegedOpcode;
+ case ILL_PRVREG:
+ return CrashReason::ePrivilegedRegister;
+ case ILL_COPROC:
+ return CrashReason::eCoprocessorError;
+ case ILL_BADSTK:
+ return CrashReason::eInternalStackError;
+ }
+
+ assert(false && "unexpected si_code for SIGILL");
+ return CrashReason::eInvalidCrashReason;
+}
+
+CrashReason
+GetCrashReasonForSIGFPE(const siginfo_t& info)
+{
+ assert(info.si_signo == SIGFPE);
+
+ switch (info.si_code)
+ {
+ case FPE_INTDIV:
+ return CrashReason::eIntegerDivideByZero;
+ case FPE_INTOVF:
+ return CrashReason::eIntegerOverflow;
+ case FPE_FLTDIV:
+ return CrashReason::eFloatDivideByZero;
+ case FPE_FLTOVF:
+ return CrashReason::eFloatOverflow;
+ case FPE_FLTUND:
+ return CrashReason::eFloatUnderflow;
+ case FPE_FLTRES:
+ return CrashReason::eFloatInexactResult;
+ case FPE_FLTINV:
+ return CrashReason::eFloatInvalidOperation;
+ case FPE_FLTSUB:
+ return CrashReason::eFloatSubscriptRange;
+ }
+
+ assert(false && "unexpected si_code for SIGFPE");
+ return CrashReason::eInvalidCrashReason;
+}
+
+CrashReason
+GetCrashReasonForSIGBUS(const siginfo_t& info)
+{
+ assert(info.si_signo == SIGBUS);
+
+ switch (info.si_code)
+ {
+ case BUS_ADRALN:
+ return CrashReason::eIllegalAlignment;
+ case BUS_ADRERR:
+ return CrashReason::eIllegalAddress;
+ case BUS_OBJERR:
+ return CrashReason::eHardwareError;
+ }
+
+ assert(false && "unexpected si_code for SIGBUS");
+ return CrashReason::eInvalidCrashReason;
+}
+
+}
+
+std::string
+GetCrashReasonString (CrashReason reason, lldb::addr_t fault_addr)
+{
+ std::string str;
+
+ switch (reason)
+ {
+ default:
+ assert(false && "invalid CrashReason");
+ break;
+
+ case CrashReason::eInvalidAddress:
+ str = "invalid address";
+ AppendFaultAddr (str, fault_addr);
+ break;
+ case CrashReason::ePrivilegedAddress:
+ str = "address access protected";
+ AppendFaultAddr (str, fault_addr);
+ break;
+ case CrashReason::eIllegalOpcode:
+ str = "illegal instruction";
+ break;
+ case CrashReason::eIllegalOperand:
+ str = "illegal instruction operand";
+ break;
+ case CrashReason::eIllegalAddressingMode:
+ str = "illegal addressing mode";
+ break;
+ case CrashReason::eIllegalTrap:
+ str = "illegal trap";
+ break;
+ case CrashReason::ePrivilegedOpcode:
+ str = "privileged instruction";
+ break;
+ case CrashReason::ePrivilegedRegister:
+ str = "privileged register";
+ break;
+ case CrashReason::eCoprocessorError:
+ str = "coprocessor error";
+ break;
+ case CrashReason::eInternalStackError:
+ str = "internal stack error";
+ break;
+ case CrashReason::eIllegalAlignment:
+ str = "illegal alignment";
+ break;
+ case CrashReason::eIllegalAddress:
+ str = "illegal address";
+ break;
+ case CrashReason::eHardwareError:
+ str = "hardware error";
+ break;
+ case CrashReason::eIntegerDivideByZero:
+ str = "integer divide by zero";
+ break;
+ case CrashReason::eIntegerOverflow:
+ str = "integer overflow";
+ break;
+ case CrashReason::eFloatDivideByZero:
+ str = "floating point divide by zero";
+ break;
+ case CrashReason::eFloatOverflow:
+ str = "floating point overflow";
+ break;
+ case CrashReason::eFloatUnderflow:
+ str = "floating point underflow";
+ break;
+ case CrashReason::eFloatInexactResult:
+ str = "inexact floating point result";
+ break;
+ case CrashReason::eFloatInvalidOperation:
+ str = "invalid floating point operation";
+ break;
+ case CrashReason::eFloatSubscriptRange:
+ str = "invalid floating point subscript range";
+ break;
+ }
+
+ return str;
+}
+
+const char *
+CrashReasonAsString (CrashReason reason)
+{
+#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
+ // Just return the code in ascii for integration builds.
+ chcar str[8];
+ sprintf(str, "%d", reason);
+#else
+ const char *str = nullptr;
+
+ switch (reason)
+ {
+ case CrashReason::eInvalidCrashReason:
+ str = "eInvalidCrashReason";
+ break;
+
+ // SIGSEGV crash reasons.
+ case CrashReason::eInvalidAddress:
+ str = "eInvalidAddress";
+ break;
+ case CrashReason::ePrivilegedAddress:
+ str = "ePrivilegedAddress";
+ break;
+
+ // SIGILL crash reasons.
+ case CrashReason::eIllegalOpcode:
+ str = "eIllegalOpcode";
+ break;
+ case CrashReason::eIllegalOperand:
+ str = "eIllegalOperand";
+ break;
+ case CrashReason::eIllegalAddressingMode:
+ str = "eIllegalAddressingMode";
+ break;
+ case CrashReason::eIllegalTrap:
+ str = "eIllegalTrap";
+ break;
+ case CrashReason::ePrivilegedOpcode:
+ str = "ePrivilegedOpcode";
+ break;
+ case CrashReason::ePrivilegedRegister:
+ str = "ePrivilegedRegister";
+ break;
+ case CrashReason::eCoprocessorError:
+ str = "eCoprocessorError";
+ break;
+ case CrashReason::eInternalStackError:
+ str = "eInternalStackError";
+ break;
+
+ // SIGBUS crash reasons:
+ case CrashReason::eIllegalAlignment:
+ str = "eIllegalAlignment";
+ break;
+ case CrashReason::eIllegalAddress:
+ str = "eIllegalAddress";
+ break;
+ case CrashReason::eHardwareError:
+ str = "eHardwareError";
+ break;
+
+ // SIGFPE crash reasons:
+ case CrashReason::eIntegerDivideByZero:
+ str = "eIntegerDivideByZero";
+ break;
+ case CrashReason::eIntegerOverflow:
+ str = "eIntegerOverflow";
+ break;
+ case CrashReason::eFloatDivideByZero:
+ str = "eFloatDivideByZero";
+ break;
+ case CrashReason::eFloatOverflow:
+ str = "eFloatOverflow";
+ break;
+ case CrashReason::eFloatUnderflow:
+ str = "eFloatUnderflow";
+ break;
+ case CrashReason::eFloatInexactResult:
+ str = "eFloatInexactResult";
+ break;
+ case CrashReason::eFloatInvalidOperation:
+ str = "eFloatInvalidOperation";
+ break;
+ case CrashReason::eFloatSubscriptRange:
+ str = "eFloatSubscriptRange";
+ break;
+ }
+#endif
+
+ return str;
+}
+
+CrashReason
+GetCrashReason(const siginfo_t& info)
+{
+ switch(info.si_signo)
+ {
+ case SIGSEGV:
+ return GetCrashReasonForSIGSEGV(info);
+ case SIGBUS:
+ return GetCrashReasonForSIGBUS(info);
+ case SIGFPE:
+ return GetCrashReasonForSIGFPE(info);
+ case SIGILL:
+ return GetCrashReasonForSIGILL(info);
+ }
+
+ assert(false && "unexpected signal");
+ return CrashReason::eInvalidCrashReason;
+}
diff --git a/source/Plugins/Process/POSIX/CrashReason.h b/source/Plugins/Process/POSIX/CrashReason.h
new file mode 100644
index 000000000000..f6d9ba553e4a
--- /dev/null
+++ b/source/Plugins/Process/POSIX/CrashReason.h
@@ -0,0 +1,62 @@
+//===-- CrashReason.h -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CrashReason_H_
+#define liblldb_CrashReason_H_
+
+#include "lldb/lldb-types.h"
+
+#include <signal.h>
+
+#include <string>
+
+enum class CrashReason
+{
+ eInvalidCrashReason,
+
+ // SIGSEGV crash reasons.
+ eInvalidAddress,
+ ePrivilegedAddress,
+
+ // SIGILL crash reasons.
+ eIllegalOpcode,
+ eIllegalOperand,
+ eIllegalAddressingMode,
+ eIllegalTrap,
+ ePrivilegedOpcode,
+ ePrivilegedRegister,
+ eCoprocessorError,
+ eInternalStackError,
+
+ // SIGBUS crash reasons,
+ eIllegalAlignment,
+ eIllegalAddress,
+ eHardwareError,
+
+ // SIGFPE crash reasons,
+ eIntegerDivideByZero,
+ eIntegerOverflow,
+ eFloatDivideByZero,
+ eFloatOverflow,
+ eFloatUnderflow,
+ eFloatInexactResult,
+ eFloatInvalidOperation,
+ eFloatSubscriptRange
+};
+
+std::string
+GetCrashReasonString (CrashReason reason, lldb::addr_t fault_addr);
+
+const char *
+CrashReasonAsString (CrashReason reason);
+
+CrashReason
+GetCrashReason(const siginfo_t& info);
+
+#endif // #ifndef liblldb_CrashReason_H_
diff --git a/source/Plugins/Process/POSIX/POSIXStopInfo.cpp b/source/Plugins/Process/POSIX/POSIXStopInfo.cpp
index 6e2c140682ba..3b8cea737bcb 100644
--- a/source/Plugins/Process/POSIX/POSIXStopInfo.cpp
+++ b/source/Plugins/Process/POSIX/POSIXStopInfo.cpp
@@ -45,6 +45,15 @@ POSIXLimboStopInfo::ShouldNotify(Event *event_ptr)
//===----------------------------------------------------------------------===//
// POSIXCrashStopInfo
+POSIXCrashStopInfo::POSIXCrashStopInfo(POSIXThread &thread,
+ uint32_t status,
+ CrashReason reason,
+ lldb::addr_t fault_addr)
+ : POSIXStopInfo(thread, status)
+{
+ m_description = ::GetCrashReasonString(reason, fault_addr);
+}
+
POSIXCrashStopInfo::~POSIXCrashStopInfo() { }
lldb::StopReason
@@ -53,12 +62,6 @@ POSIXCrashStopInfo::GetStopReason() const
return lldb::eStopReasonException;
}
-const char *
-POSIXCrashStopInfo::GetDescription()
-{
- return ProcessMessage::GetCrashReasonString(m_crash_reason, m_fault_addr);
-}
-
//===----------------------------------------------------------------------===//
// POSIXNewThreadStopInfo
diff --git a/source/Plugins/Process/POSIX/POSIXStopInfo.h b/source/Plugins/Process/POSIX/POSIXStopInfo.h
index cbf309e53506..a1ee2ea68524 100644
--- a/source/Plugins/Process/POSIX/POSIXStopInfo.h
+++ b/source/Plugins/Process/POSIX/POSIXStopInfo.h
@@ -16,8 +16,10 @@
// Project includes
#include "lldb/Target/StopInfo.h"
+#include "CrashReason.h"
#include "POSIXThread.h"
-#include "ProcessMessage.h"
+
+#include <string>
//===----------------------------------------------------------------------===//
/// @class POSIXStopInfo
@@ -69,25 +71,13 @@ class POSIXCrashStopInfo
{
public:
POSIXCrashStopInfo(POSIXThread &thread, uint32_t status,
- ProcessMessage::CrashReason reason,
- lldb::addr_t fault_addr)
- : POSIXStopInfo(thread, status),
- m_crash_reason(reason),
- m_fault_addr(fault_addr)
- { }
-
+ CrashReason reason,
+ lldb::addr_t fault_addr);
~POSIXCrashStopInfo();
lldb::StopReason
GetStopReason() const;
-
- const char *
- GetDescription();
-
-private:
- ProcessMessage::CrashReason m_crash_reason;
- lldb::addr_t m_fault_addr;
-};
+};
//===----------------------------------------------------------------------===//
/// @class POSIXNewThreadStopInfo
diff --git a/source/Plugins/Process/POSIX/ProcessMessage.cpp b/source/Plugins/Process/POSIX/ProcessMessage.cpp
index 5c53627f9e0b..02049a2af953 100644
--- a/source/Plugins/Process/POSIX/ProcessMessage.cpp
+++ b/source/Plugins/Process/POSIX/ProcessMessage.cpp
@@ -9,205 +9,19 @@
#include "ProcessMessage.h"
-#include <sstream>
-
using namespace lldb_private;
-namespace {
-
-inline void AppendFaultAddr(std::string& str, lldb::addr_t addr)
-{
- std::stringstream ss;
- ss << " (fault address: 0x" << std::hex << addr << ")";
- str += ss.str();
-}
-
-}
-
-const char *
-ProcessMessage::GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr)
-{
- static std::string str;
-
- switch (reason)
- {
- default:
- assert(false && "invalid CrashReason");
- break;
-
- case eInvalidAddress:
- str = "invalid address";
- AppendFaultAddr(str, fault_addr);
- break;
- case ePrivilegedAddress:
- str = "address access protected";
- AppendFaultAddr(str, fault_addr);
- break;
- case eIllegalOpcode:
- str = "illegal instruction";
- break;
- case eIllegalOperand:
- str = "illegal instruction operand";
- break;
- case eIllegalAddressingMode:
- str = "illegal addressing mode";
- break;
- case eIllegalTrap:
- str = "illegal trap";
- break;
- case ePrivilegedOpcode:
- str = "privileged instruction";
- break;
- case ePrivilegedRegister:
- str = "privileged register";
- break;
- case eCoprocessorError:
- str = "coprocessor error";
- break;
- case eInternalStackError:
- str = "internal stack error";
- break;
- case eIllegalAlignment:
- str = "illegal alignment";
- break;
- case eIllegalAddress:
- str = "illegal address";
- break;
- case eHardwareError:
- str = "hardware error";
- break;
- case eIntegerDivideByZero:
- str = "integer divide by zero";
- break;
- case eIntegerOverflow:
- str = "integer overflow";
- break;
- case eFloatDivideByZero:
- str = "floating point divide by zero";
- break;
- case eFloatOverflow:
- str = "floating point overflow";
- break;
- case eFloatUnderflow:
- str = "floating point underflow";
- break;
- case eFloatInexactResult:
- str = "inexact floating point result";
- break;
- case eFloatInvalidOperation:
- str = "invalid floating point operation";
- break;
- case eFloatSubscriptRange:
- str = "invalid floating point subscript range";
- break;
- }
-
- return str.c_str();
-}
-
-const char *
-ProcessMessage::PrintCrashReason(CrashReason reason)
-{
-#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
- // Just return the code in asci for integration builds.
- chcar str[8];
- sprintf(str, "%d", reason);
-#else
- const char *str = NULL;
-
- switch (reason)
- {
- case eInvalidCrashReason:
- str = "eInvalidCrashReason";
- break;
-
- // SIGSEGV crash reasons.
- case eInvalidAddress:
- str = "eInvalidAddress";
- break;
- case ePrivilegedAddress:
- str = "ePrivilegedAddress";
- break;
-
- // SIGILL crash reasons.
- case eIllegalOpcode:
- str = "eIllegalOpcode";
- break;
- case eIllegalOperand:
- str = "eIllegalOperand";
- break;
- case eIllegalAddressingMode:
- str = "eIllegalAddressingMode";
- break;
- case eIllegalTrap:
- str = "eIllegalTrap";
- break;
- case ePrivilegedOpcode:
- str = "ePrivilegedOpcode";
- break;
- case ePrivilegedRegister:
- str = "ePrivilegedRegister";
- break;
- case eCoprocessorError:
- str = "eCoprocessorError";
- break;
- case eInternalStackError:
- str = "eInternalStackError";
- break;
-
- // SIGBUS crash reasons:
- case eIllegalAlignment:
- str = "eIllegalAlignment";
- break;
- case eIllegalAddress:
- str = "eIllegalAddress";
- break;
- case eHardwareError:
- str = "eHardwareError";
- break;
-
- // SIGFPE crash reasons:
- case eIntegerDivideByZero:
- str = "eIntegerDivideByZero";
- break;
- case eIntegerOverflow:
- str = "eIntegerOverflow";
- break;
- case eFloatDivideByZero:
- str = "eFloatDivideByZero";
- break;
- case eFloatOverflow:
- str = "eFloatOverflow";
- break;
- case eFloatUnderflow:
- str = "eFloatUnderflow";
- break;
- case eFloatInexactResult:
- str = "eFloatInexactResult";
- break;
- case eFloatInvalidOperation:
- str = "eFloatInvalidOperation";
- break;
- case eFloatSubscriptRange:
- str = "eFloatSubscriptRange";
- break;
- }
-#endif
-
- return str;
-}
-
const char *
ProcessMessage::PrintCrashReason() const
{
- return PrintCrashReason(m_crash_reason);
+ return CrashReasonAsString(m_crash_reason);
}
const char *
ProcessMessage::PrintKind(Kind kind)
{
#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
- // Just return the code in asci for integration builds.
+ // Just return the code in ascii for integration builds.
chcar str[8];
sprintf(str, "%d", reason);
#else
diff --git a/source/Plugins/Process/POSIX/ProcessMessage.h b/source/Plugins/Process/POSIX/ProcessMessage.h
index 40462d0f0e13..f932e9fff278 100644
--- a/source/Plugins/Process/POSIX/ProcessMessage.h
+++ b/source/Plugins/Process/POSIX/ProcessMessage.h
@@ -10,7 +10,10 @@
#ifndef liblldb_ProcessMessage_H_
#define liblldb_ProcessMessage_H_
+#include "CrashReason.h"
+
#include <cassert>
+#include <string>
#include "lldb/lldb-defines.h"
#include "lldb/lldb-types.h"
@@ -36,44 +39,10 @@ public:
eExecMessage
};
- enum CrashReason
- {
- eInvalidCrashReason,
-
- // SIGSEGV crash reasons.
- eInvalidAddress,
- ePrivilegedAddress,
-
- // SIGILL crash reasons.
- eIllegalOpcode,
- eIllegalOperand,
- eIllegalAddressingMode,
- eIllegalTrap,
- ePrivilegedOpcode,
- ePrivilegedRegister,
- eCoprocessorError,
- eInternalStackError,
-
- // SIGBUS crash reasons,
- eIllegalAlignment,
- eIllegalAddress,
- eHardwareError,
-
- // SIGFPE crash reasons,
- eIntegerDivideByZero,
- eIntegerOverflow,
- eFloatDivideByZero,
- eFloatOverflow,
- eFloatUnderflow,
- eFloatInexactResult,
- eFloatInvalidOperation,
- eFloatSubscriptRange
- };
-
ProcessMessage()
: m_tid(LLDB_INVALID_PROCESS_ID),
m_kind(eInvalidMessage),
- m_crash_reason(eInvalidCrashReason),
+ m_crash_reason(CrashReason::eInvalidCrashReason),
m_status(0),
m_addr(0) { }
@@ -175,15 +144,9 @@ public:
return m_child_tid;
}
- static const char *
- GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr);
-
const char *
PrintCrashReason() const;
- static const char *
- PrintCrashReason(CrashReason reason);
-
const char *
PrintKind() const;
@@ -195,7 +158,7 @@ private:
int status = 0, lldb::addr_t addr = 0)
: m_tid(tid),
m_kind(kind),
- m_crash_reason(eInvalidCrashReason),
+ m_crash_reason(CrashReason::eInvalidCrashReason),
m_status(status),
m_addr(addr),
m_child_tid(0) { }
@@ -203,14 +166,14 @@ private:
ProcessMessage(lldb::tid_t tid, Kind kind, lldb::tid_t child_tid)
: m_tid(tid),
m_kind(kind),
- m_crash_reason(eInvalidCrashReason),
+ m_crash_reason(CrashReason::eInvalidCrashReason),
m_status(0),
m_addr(0),
m_child_tid(child_tid) { }
lldb::tid_t m_tid;
Kind m_kind : 8;
- CrashReason m_crash_reason : 8;
+ CrashReason m_crash_reason;
int m_status;
lldb::addr_t m_addr;
lldb::tid_t m_child_tid;
diff --git a/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
index 0e5ab5a8d8b1..882fac75c9a0 100644
--- a/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
+++ b/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
@@ -252,7 +252,16 @@ ProcessPOSIX::DoLaunch (Module *module,
if (!error.Success())
return error;
- SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
+ int terminal = m_monitor->GetTerminalFD();
+ if (terminal >= 0) {
+ // The reader thread will close the file descriptor when done, so we pass it a copy.
+ int stdio = fcntl(terminal, F_DUPFD_CLOEXEC, 0);
+ if (stdio == -1) {
+ error.SetErrorToErrno();
+ return error;
+ }
+ SetSTDIOFileDescriptor(stdio);
+ }
SetID(m_monitor->GetPID());
return error;
diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp
index b542db4779db..80e1c1984225 100644
--- a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp
+++ b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp
@@ -38,14 +38,21 @@ RegisterContextPOSIXProcessMonitor_powerpc::GetMonitor()
bool
RegisterContextPOSIXProcessMonitor_powerpc::ReadGPR()
{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
}
bool
RegisterContextPOSIXProcessMonitor_powerpc::ReadFPR()
{
- // XXX not yet implemented
+ 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;
}
@@ -59,7 +66,14 @@ RegisterContextPOSIXProcessMonitor_powerpc::WriteGPR()
bool
RegisterContextPOSIXProcessMonitor_powerpc::WriteFPR()
{
- // XXX not yet implemented
+ 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;
}
@@ -146,26 +160,15 @@ RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const RegisterInfo *reg
{
if (!ReadFPR())
return false;
+ uint8_t *src = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
+ value.SetUInt64(*(uint64_t*)src);
}
- else
+ else if (IsGPR(reg))
{
- 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);
+ bool success = ReadRegister(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)
@@ -183,7 +186,16 @@ RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(const RegisterInfo *re
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;
}
@@ -221,6 +233,9 @@ RegisterContextPOSIXProcessMonitor_powerpc::WriteAllRegisterValues(const DataBuf
if (WriteGPR())
{
src += GetGPRSize();
+ ::memcpy (&m_fpr_powerpc, src, sizeof(m_fpr_powerpc));
+
+ success = WriteFPR();
}
}
}
diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h
index 92a331285515..5c686df4836f 100644
--- a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h
+++ b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h
@@ -23,17 +23,26 @@ public:
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);
diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index 1088924bfeac..25a195e11a03 100644
--- a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -15,7 +15,7 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/DataFormatters/FormatManager.h"
@@ -158,8 +158,8 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict
regex_match.GetMatchAtIndex(slice_cstr, 2, msbit_str) &&
regex_match.GetMatchAtIndex(slice_cstr, 3, lsbit_str))
{
- const uint32_t msbit = Args::StringToUInt32(msbit_str.c_str(), UINT32_MAX);
- const uint32_t lsbit = Args::StringToUInt32(lsbit_str.c_str(), UINT32_MAX);
+ const uint32_t msbit = StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX);
+ const uint32_t lsbit = StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX);
if (msbit != UINT32_MAX && lsbit != UINT32_MAX)
{
if (msbit > lsbit)
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp b/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
index 5170e6d2accb..5133d6088bd3 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
@@ -134,6 +134,45 @@ typedef struct _FPR
uint64_t fpscr;
} FPR;
+typedef struct _VMX
+{
+ uint32_t v0[4];
+ uint32_t v1[4];
+ uint32_t v2[4];
+ uint32_t v3[4];
+ uint32_t v4[4];
+ uint32_t v5[4];
+ uint32_t v6[4];
+ uint32_t v7[4];
+ uint32_t v8[4];
+ uint32_t v9[4];
+ uint32_t v10[4];
+ uint32_t v11[4];
+ uint32_t v12[4];
+ uint32_t v13[4];
+ uint32_t v14[4];
+ uint32_t v15[4];
+ uint32_t v16[4];
+ uint32_t v17[4];
+ uint32_t v18[4];
+ uint32_t v19[4];
+ uint32_t v20[4];
+ uint32_t v21[4];
+ uint32_t v22[4];
+ uint32_t v23[4];
+ uint32_t v24[4];
+ uint32_t v25[4];
+ uint32_t v26[4];
+ uint32_t v27[4];
+ uint32_t v28[4];
+ uint32_t v29[4];
+ uint32_t v30[4];
+ uint32_t v31[4];
+ uint32_t pad[2];
+ uint32_t vrsave;
+ uint32_t vscr;
+} VMX;
+
//---------------------------------------------------------------------------
// Include RegisterInfos_powerpc to declare our g_register_infos_powerpc structure.
//---------------------------------------------------------------------------
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index f47d687702ec..1b3a9491d1c8 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -811,7 +811,7 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame ()
if (m_frame_type == eTrapHandlerFrame && process)
{
m_fast_unwind_plan_sp.reset();
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (process->GetTarget(), m_current_offset_backed_up_one);
+ unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan (process->GetTarget(), m_current_offset_backed_up_one);
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc) && unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes)
{
return unwind_plan_sp;
@@ -826,7 +826,10 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame ()
// But there is not.
if (process && process->GetDynamicLoader() && process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo (m_sym_ctx))
{
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (process->GetTarget(), m_current_offset_backed_up_one);
+ // We must specifically call the GetEHFrameUnwindPlan() method here -- normally we would
+ // call GetUnwindPlanAtCallSite() -- because CallSite may return an unwind plan sourced from
+ // either eh_frame (that's what we intend) or compact unwind (this won't work)
+ unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan (process->GetTarget(), m_current_offset_backed_up_one);
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
{
UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan because the DynamicLoader suggested we prefer it",
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
index b9b9dca07be4..b38d6cc60cac 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
@@ -125,3 +125,8 @@ RegisterContextLinux_i386::GetRegisterCount () const
return static_cast<uint32_t> (sizeof (g_register_infos_i386) / sizeof (g_register_infos_i386 [0]));
}
+uint32_t
+RegisterContextLinux_i386::GetUserRegisterCount () const
+{
+ return static_cast<uint32_t> (k_num_user_registers_i386);
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_i386.h b/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
index f8b21fc8e87d..cb71d7993e17 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_i386.h
@@ -26,6 +26,9 @@ public:
uint32_t
GetRegisterCount () const override;
+
+ uint32_t
+ GetUserRegisterCount () const override;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
index 74f016bd744d..5c93ebf88faa 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
@@ -145,10 +145,26 @@ GetRegisterInfoCount (const ArchSpec &target_arch)
}
}
+static uint32_t
+GetUserRegisterInfoCount (const ArchSpec &target_arch)
+{
+ switch (target_arch.GetMachine())
+ {
+ case llvm::Triple::x86:
+ return static_cast<uint32_t> (k_num_user_registers_i386);
+ case llvm::Triple::x86_64:
+ return static_cast<uint32_t> (k_num_user_registers_x86_64);
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
+}
+
RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(const ArchSpec &target_arch) :
lldb_private::RegisterInfoInterface(target_arch),
m_register_info_p (GetRegisterInfoPtr (target_arch)),
- m_register_info_count (GetRegisterInfoCount (target_arch))
+ m_register_info_count (GetRegisterInfoCount (target_arch)),
+ m_user_register_count (GetUserRegisterInfoCount (target_arch))
{
}
@@ -169,3 +185,9 @@ RegisterContextLinux_x86_64::GetRegisterCount () const
{
return m_register_info_count;
}
+
+uint32_t
+RegisterContextLinux_x86_64::GetUserRegisterCount () const
+{
+ return m_user_register_count;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h b/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
index 7b6828661c1e..0cdfae9ac943 100644
--- a/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
@@ -27,9 +27,13 @@ public:
uint32_t
GetRegisterCount () const override;
+ uint32_t
+ GetUserRegisterCount () const override;
+
private:
const lldb_private::RegisterInfo *m_register_info_p;
uint32_t m_register_info_count;
+ uint32_t m_user_register_count;
};
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
index a9477d583517..828fb2571f79 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
@@ -106,10 +106,49 @@ uint32_t g_fpr_regnums[] =
fpr_fpscr_powerpc,
};
+static const
+uint32_t g_vmx_regnums[] =
+{
+ vmx_v0_powerpc,
+ vmx_v1_powerpc,
+ vmx_v2_powerpc,
+ vmx_v3_powerpc,
+ vmx_v4_powerpc,
+ vmx_v5_powerpc,
+ vmx_v6_powerpc,
+ vmx_v7_powerpc,
+ vmx_v8_powerpc,
+ vmx_v9_powerpc,
+ vmx_v10_powerpc,
+ vmx_v11_powerpc,
+ vmx_v12_powerpc,
+ vmx_v13_powerpc,
+ vmx_v14_powerpc,
+ vmx_v15_powerpc,
+ vmx_v16_powerpc,
+ vmx_v17_powerpc,
+ vmx_v18_powerpc,
+ vmx_v19_powerpc,
+ vmx_v20_powerpc,
+ vmx_v21_powerpc,
+ vmx_v22_powerpc,
+ vmx_v23_powerpc,
+ vmx_v24_powerpc,
+ vmx_v25_powerpc,
+ vmx_v26_powerpc,
+ vmx_v27_powerpc,
+ vmx_v28_powerpc,
+ vmx_v29_powerpc,
+ vmx_v30_powerpc,
+ vmx_v31_powerpc,
+ vmx_vrsave_powerpc,
+ vmx_vscr_powerpc,
+};
+
// Number of register sets provided by this context.
enum
{
- k_num_register_sets = 2
+ k_num_register_sets = 3
};
static const RegisterSet
@@ -117,20 +156,26 @@ 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 },
+ { "Altivec/VMX Registers", "vmx", k_num_vmx_registers_powerpc, g_vmx_regnums },
};
bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg)
{
- return reg <= k_num_gpr_registers_powerpc; // GPR's come first.
+ return (reg >= k_first_gpr_powerpc) && (reg <= k_last_gpr_powerpc); // GPR's come first.
}
bool
RegisterContextPOSIX_powerpc::IsFPR(unsigned reg)
{
- // XXX
return (reg >= k_first_fpr) && (reg <= k_last_fpr);
}
+bool
+RegisterContextPOSIX_powerpc::IsVMX(unsigned reg)
+{
+ return (reg >= k_first_vmx) && (reg <= k_last_vmx);
+}
+
RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(Thread &thread,
uint32_t concrete_frame_idx,
RegisterInfoInterface *register_info)
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
index 3194c3968c98..c7a2451d7811 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
@@ -97,9 +97,47 @@ enum
fpr_fpscr_powerpc,
k_last_fpr = fpr_fpscr_powerpc,
+ k_first_vmx,
+ vmx_v0_powerpc = k_first_vmx,
+ vmx_v1_powerpc,
+ vmx_v2_powerpc,
+ vmx_v3_powerpc,
+ vmx_v4_powerpc,
+ vmx_v5_powerpc,
+ vmx_v6_powerpc,
+ vmx_v7_powerpc,
+ vmx_v8_powerpc,
+ vmx_v9_powerpc,
+ vmx_v10_powerpc,
+ vmx_v11_powerpc,
+ vmx_v12_powerpc,
+ vmx_v13_powerpc,
+ vmx_v14_powerpc,
+ vmx_v15_powerpc,
+ vmx_v16_powerpc,
+ vmx_v17_powerpc,
+ vmx_v18_powerpc,
+ vmx_v19_powerpc,
+ vmx_v20_powerpc,
+ vmx_v21_powerpc,
+ vmx_v22_powerpc,
+ vmx_v23_powerpc,
+ vmx_v24_powerpc,
+ vmx_v25_powerpc,
+ vmx_v26_powerpc,
+ vmx_v27_powerpc,
+ vmx_v28_powerpc,
+ vmx_v29_powerpc,
+ vmx_v30_powerpc,
+ vmx_v31_powerpc,
+ vmx_vrsave_powerpc,
+ vmx_vscr_powerpc,
+ k_last_vmx = vmx_vscr_powerpc,
+
k_num_registers_powerpc,
k_num_gpr_registers_powerpc = k_last_gpr_powerpc - k_first_gpr_powerpc + 1,
k_num_fpr_registers_powerpc = k_last_fpr - k_first_fpr + 1,
+ k_num_vmx_registers_powerpc = k_last_vmx - k_first_vmx + 1,
};
class RegisterContextPOSIX_powerpc
@@ -147,6 +185,8 @@ public:
protected:
uint64_t m_gpr_powerpc[k_num_gpr_registers_powerpc]; // general purpose registers.
+ uint64_t m_fpr_powerpc[k_num_fpr_registers_powerpc]; // floating point registers.
+ uint32_t m_vmx_powerpc[k_num_vmx_registers_powerpc][4];
std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
// Determines if an extended register set is supported on the processor running the inferior process.
@@ -162,12 +202,17 @@ protected:
bool
IsFPR(unsigned reg);
+ bool
+ IsVMX(unsigned reg);
+
lldb::ByteOrder GetByteOrder();
virtual bool ReadGPR() = 0;
virtual bool ReadFPR() = 0;
+ virtual bool ReadVMX() = 0;
virtual bool WriteGPR() = 0;
virtual bool WriteFPR() = 0;
+ virtual bool WriteVMX() = 0;
};
#endif // #ifndef liblldb_RegisterContextPOSIX_powerpc_H_
diff --git a/source/Plugins/Process/Utility/RegisterContext_powerpc.h b/source/Plugins/Process/Utility/RegisterContext_powerpc.h
index cf54cc0c2145..7438b88971b3 100644
--- a/source/Plugins/Process/Utility/RegisterContext_powerpc.h
+++ b/source/Plugins/Process/Utility/RegisterContext_powerpc.h
@@ -79,10 +79,45 @@ enum
gcc_dwarf_f31_powerpc,
gcc_dwarf_cr_powerpc,
gcc_dwarf_fpscr_powerpc,
+ gcc_dwarf_msr_powerpc,
+ gcc_dwarf_vscr_powerpc,
gcc_dwarf_xer_powerpc = 101,
gcc_dwarf_lr_powerpc = 108,
gcc_dwarf_ctr_powerpc,
gcc_dwarf_pc_powerpc,
+ gcc_dwarf_vrsave_powerpc = 356,
+ gcc_dwarf_v0_powerpc = 1124,
+ gcc_dwarf_v1_powerpc,
+ gcc_dwarf_v2_powerpc,
+ gcc_dwarf_v3_powerpc,
+ gcc_dwarf_v4_powerpc,
+ gcc_dwarf_v5_powerpc,
+ gcc_dwarf_v6_powerpc,
+ gcc_dwarf_v7_powerpc,
+ gcc_dwarf_v8_powerpc,
+ gcc_dwarf_v9_powerpc,
+ gcc_dwarf_v10_powerpc,
+ gcc_dwarf_v11_powerpc,
+ gcc_dwarf_v12_powerpc,
+ gcc_dwarf_v13_powerpc,
+ gcc_dwarf_v14_powerpc,
+ gcc_dwarf_v15_powerpc,
+ gcc_dwarf_v16_powerpc,
+ gcc_dwarf_v17_powerpc,
+ gcc_dwarf_v18_powerpc,
+ gcc_dwarf_v19_powerpc,
+ gcc_dwarf_v20_powerpc,
+ gcc_dwarf_v21_powerpc,
+ gcc_dwarf_v22_powerpc,
+ gcc_dwarf_v23_powerpc,
+ gcc_dwarf_v24_powerpc,
+ gcc_dwarf_v25_powerpc,
+ gcc_dwarf_v26_powerpc,
+ gcc_dwarf_v27_powerpc,
+ gcc_dwarf_v28_powerpc,
+ gcc_dwarf_v29_powerpc,
+ gcc_dwarf_v30_powerpc,
+ gcc_dwarf_v31_powerpc,
};
// GDB Register numbers (eRegisterKindGDB)
@@ -152,12 +187,46 @@ enum
gdb_f29_powerpc,
gdb_f30_powerpc,
gdb_f31_powerpc,
- gdb_cr_powerpc,
- gdb_fpscr_powerpc,
- gdb_xer_powerpc = 101,
- gdb_lr_powerpc = 108,
- gdb_ctr_powerpc,
gdb_pc_powerpc,
+ gdb_cr_powerpc = 66,
+ gdb_lr_powerpc,
+ gdb_ctr_powerpc,
+ gdb_xer_powerpc,
+ gdb_fpscr_powerpc,
+ gdb_v0_powerpc = 106,
+ gdb_v1_powerpc,
+ gdb_v2_powerpc,
+ gdb_v3_powerpc,
+ gdb_v4_powerpc,
+ gdb_v5_powerpc,
+ gdb_v6_powerpc,
+ gdb_v7_powerpc,
+ gdb_v8_powerpc,
+ gdb_v9_powerpc,
+ gdb_v10_powerpc,
+ gdb_v11_powerpc,
+ gdb_v12_powerpc,
+ gdb_v13_powerpc,
+ gdb_v14_powerpc,
+ gdb_v15_powerpc,
+ gdb_v16_powerpc,
+ gdb_v17_powerpc,
+ gdb_v18_powerpc,
+ gdb_v19_powerpc,
+ gdb_v20_powerpc,
+ gdb_v21_powerpc,
+ gdb_v22_powerpc,
+ gdb_v23_powerpc,
+ gdb_v24_powerpc,
+ gdb_v25_powerpc,
+ gdb_v26_powerpc,
+ gdb_v27_powerpc,
+ gdb_v28_powerpc,
+ gdb_v29_powerpc,
+ gdb_v30_powerpc,
+ gdb_v31_powerpc,
+ gdb_vscr_powerpc,
+ gdb_vrsave_powerpc,
};
#endif // liblldb_RegisterContext_powerpc_H_
diff --git a/source/Plugins/Process/Utility/RegisterInfoInterface.h b/source/Plugins/Process/Utility/RegisterInfoInterface.h
index 382475f4523a..94cb5cc791c6 100644
--- a/source/Plugins/Process/Utility/RegisterInfoInterface.h
+++ b/source/Plugins/Process/Utility/RegisterInfoInterface.h
@@ -32,9 +32,20 @@ namespace lldb_private
virtual const lldb_private::RegisterInfo *
GetRegisterInfo () const = 0;
+ // Returns the number of registers including the user registers and the
+ // lldb internal registers also
virtual uint32_t
GetRegisterCount () const = 0;
+ // Returns the number of the user registers (excluding the registers
+ // kept for lldb internal use only). Subclasses should override it if
+ // they belongs to an architecture with lldb internal registers.
+ virtual uint32_t
+ GetUserRegisterCount () const
+ {
+ return GetRegisterCount();
+ }
+
const lldb_private::ArchSpec&
GetTargetArchitecture() const
{ return m_target_arch; }
diff --git a/source/Plugins/Process/Utility/RegisterInfos_powerpc.h b/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
index 045426648105..fe145e99588b 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
@@ -14,6 +14,8 @@
(offsetof(GPR, regname))
#define FPR_OFFSET(regname) \
(offsetof(FPR, regname))
+#define VMX_OFFSET(regname) \
+ (offsetof(VMX, regname))
#define GPR_SIZE(regname) \
(sizeof(((GPR*)NULL)->regname))
@@ -26,6 +28,9 @@
#define DEFINE_FPR(reg, lldb_kind) \
{ #reg, NULL, 8, FPR_OFFSET(reg), eEncodingIEEE754, \
eFormatFloat, { gcc_dwarf_##reg##_powerpc, gcc_dwarf_##reg##_powerpc, lldb_kind, gdb_##reg##_powerpc, fpr_##reg##_powerpc }, NULL, NULL }
+#define DEFINE_VMX(reg, lldb_kind) \
+ { #reg, NULL, 16, VMX_OFFSET(reg), eEncodingVector, \
+ eFormatVectorOfUInt32, { gcc_dwarf_##reg##_powerpc, gcc_dwarf_##reg##_powerpc, lldb_kind, gdb_##reg##_powerpc, vmx_##reg##_powerpc }, NULL, NULL }
// General purpose registers. GCC, DWARF, Generic, GDB
#define POWERPC_REGS \
@@ -98,7 +103,42 @@
DEFINE_FPR(f29, LLDB_INVALID_REGNUM), \
DEFINE_FPR(f30, LLDB_INVALID_REGNUM), \
DEFINE_FPR(f31, LLDB_INVALID_REGNUM), \
- { "fpscr", NULL, 8, FPR_OFFSET(fpscr), eEncodingUint, eFormatHex, { gcc_dwarf_fpscr_powerpc, gcc_dwarf_fpscr_powerpc, LLDB_INVALID_REGNUM, gdb_fpscr_powerpc, fpr_fpscr_powerpc }, NULL, NULL },
+ { "fpscr", NULL, 8, FPR_OFFSET(fpscr), eEncodingUint, eFormatHex, { gcc_dwarf_fpscr_powerpc, gcc_dwarf_fpscr_powerpc, LLDB_INVALID_REGNUM, gdb_fpscr_powerpc, fpr_fpscr_powerpc }, NULL, NULL }, \
+ DEFINE_VMX(v0, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v1, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v2, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v3, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v4, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v5, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v6, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v7, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v8, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v9, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v10, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v11, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v12, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v13, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v14, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v15, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v16, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v17, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v18, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v19, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v20, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v21, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v22, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v23, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v24, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v25, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v26, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v27, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v28, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v29, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v30, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(v31, LLDB_INVALID_REGNUM), \
+ { "vrsave", NULL, 4, VMX_OFFSET(vrsave), eEncodingUint, eFormatHex, { gcc_dwarf_vrsave_powerpc, gcc_dwarf_vrsave_powerpc, LLDB_INVALID_REGNUM, gdb_vrsave_powerpc, vmx_vrsave_powerpc }, NULL, NULL }, \
+ { "vscr", NULL, 4, VMX_OFFSET(vscr), eEncodingUint, eFormatHex, { gcc_dwarf_vscr_powerpc, gcc_dwarf_vscr_powerpc, LLDB_INVALID_REGNUM, gdb_vscr_powerpc, vmx_vscr_powerpc }, NULL, NULL },
+
static RegisterInfo
g_register_infos_powerpc64[] =
{
diff --git a/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/source/Plugins/Process/Utility/lldb-x86-register-enums.h
index 99fca3005820..63027b4451b8 100644
--- a/source/Plugins/Process/Utility/lldb-x86-register-enums.h
+++ b/source/Plugins/Process/Utility/lldb-x86-register-enums.h
@@ -118,7 +118,8 @@ namespace lldb_private
k_num_registers_i386,
k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1,
k_num_fpr_registers_i386 = k_last_fpr_i386 - k_first_fpr_i386 + 1,
- k_num_avx_registers_i386 = k_last_avx_i386 - k_first_avx_i386 + 1
+ k_num_avx_registers_i386 = k_last_avx_i386 - k_first_avx_i386 + 1,
+ k_num_user_registers_i386 = k_num_gpr_registers_i386 + k_num_fpr_registers_i386 + k_num_avx_registers_i386,
};
//---------------------------------------------------------------------------
@@ -285,7 +286,8 @@ namespace lldb_private
k_num_registers_x86_64,
k_num_gpr_registers_x86_64 = k_last_gpr_x86_64 - k_first_gpr_x86_64 + 1,
k_num_fpr_registers_x86_64 = k_last_fpr_x86_64 - k_first_fpr_x86_64 + 1,
- k_num_avx_registers_x86_64 = k_last_avx_x86_64 - k_first_avx_x86_64 + 1
+ k_num_avx_registers_x86_64 = k_last_avx_x86_64 - k_first_avx_x86_64 + 1,
+ k_num_user_registers_x86_64 = k_num_gpr_registers_x86_64 + k_num_fpr_registers_x86_64 + k_num_avx_registers_x86_64,
};
}
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index fb39d7318a5a..ead959508d88 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -412,7 +412,8 @@ enum {
NT_FPREGSET,
NT_PRPSINFO,
NT_THRMISC = 7,
- NT_PROCSTAT_AUXV = 16
+ NT_PROCSTAT_AUXV = 16,
+ NT_PPC_VMX = 0x100
};
}
@@ -538,6 +539,9 @@ ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader *
// FIXME: FreeBSD sticks an int at the beginning of the note
m_auxv = DataExtractor(segment_data, note_start + 4, note_size - 4);
break;
+ case FREEBSD::NT_PPC_VMX:
+ thread_data->vregset = note_data;
+ break;
default:
break;
}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
index 15b1b44182d7..d12df21a8664 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
@@ -18,7 +18,8 @@ using namespace lldb_private;
RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(Thread &thread,
RegisterInfoInterface *register_info,
const DataExtractor &gpregset,
- const DataExtractor &fpregset)
+ const DataExtractor &fpregset,
+ const DataExtractor &vregset)
: RegisterContextPOSIX_powerpc(thread, 0, register_info)
{
m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
@@ -27,6 +28,9 @@ RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(Thread &threa
m_fpr_buffer.reset(new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
m_fpr.SetData(m_fpr_buffer);
m_fpr.SetByteOrder(fpregset.GetByteOrder());
+ m_vec_buffer.reset(new DataBufferHeap(vregset.GetDataStart(), vregset.GetByteSize()));
+ m_vec.SetData(m_vec_buffer);
+ m_vec.SetByteOrder(fpregset.GetByteOrder());
}
RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc()
@@ -46,6 +50,12 @@ RegisterContextCorePOSIX_powerpc::ReadFPR()
}
bool
+RegisterContextCorePOSIX_powerpc::ReadVMX()
+{
+ return true;
+}
+
+bool
RegisterContextCorePOSIX_powerpc::WriteGPR()
{
assert(0);
@@ -60,16 +70,31 @@ RegisterContextCorePOSIX_powerpc::WriteFPR()
}
bool
+RegisterContextCorePOSIX_powerpc::WriteVMX()
+{
+ assert(0);
+ return false;
+}
+
+bool
RegisterContextCorePOSIX_powerpc::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
{
lldb::offset_t offset = reg_info->byte_offset;
- if (reg_info->name[0] == 'f') {
+ if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size);
if (offset == reg_info->byte_offset + reg_info->byte_size)
{
value = v;
return true;
}
+ } else if (IsVMX(reg_info->kinds[lldb::eRegisterKindLLDB])) {
+ uint32_t v[4];
+ offset = m_vec.CopyData(offset, reg_info->byte_size, &v);
+ if (offset == reg_info->byte_size)
+ {
+ value.SetBytes(v, reg_info->byte_size, m_vec.GetByteOrder());
+ return true;
+ }
} else {
uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
if (offset == reg_info->byte_offset + reg_info->byte_size)
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
index e6575581b360..a3590601fa7e 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
@@ -20,7 +20,8 @@ public:
RegisterContextCorePOSIX_powerpc (lldb_private::Thread &thread,
lldb_private::RegisterInfoInterface *register_info,
const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ const lldb_private::DataExtractor &fpregset,
+ const lldb_private::DataExtractor &vregset);
~RegisterContextCorePOSIX_powerpc();
@@ -47,16 +48,24 @@ protected:
ReadFPR();
bool
+ ReadVMX();
+
+ bool
WriteGPR();
bool
WriteFPR();
+ bool
+ WriteVMX();
+
private:
lldb::DataBufferSP m_gpr_buffer;
lldb::DataBufferSP m_fpr_buffer;
+ lldb::DataBufferSP m_vec_buffer;
lldb_private::DataExtractor m_gpr;
lldb_private::DataExtractor m_fpr;
+ lldb_private::DataExtractor m_vec;
};
#endif // #ifndef liblldb_RegisterContextCorePOSIX_powerpc_H_
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index d62bcfcff600..b16335fb8e1e 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -38,7 +38,8 @@ ThreadElfCore::ThreadElfCore (Process &process, tid_t tid,
m_thread_reg_ctx_sp (),
m_signo(td.signo),
m_gpregset_data(td.gpregset),
- m_fpregset_data(td.fpregset)
+ m_fpregset_data(td.fpregset),
+ m_vregset_data(td.vregset)
{
}
@@ -148,7 +149,7 @@ ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
break;
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data));
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data, m_vregset_data));
break;
case llvm::Triple::x86:
case llvm::Triple::x86_64:
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.h b/source/Plugins/Process/elf-core/ThreadElfCore.h
index f1f00cf019b3..50502c101daf 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.h
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.h
@@ -111,6 +111,7 @@ struct ThreadData
{
lldb_private::DataExtractor gpregset;
lldb_private::DataExtractor fpregset;
+ lldb_private::DataExtractor vregset;
int signo;
std::string name;
};
@@ -170,6 +171,7 @@ protected:
lldb_private::DataExtractor m_gpregset_data;
lldb_private::DataExtractor m_fpregset_data;
+ lldb_private::DataExtractor m_vregset_data;
virtual bool CalculateStopInfo();
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 919fa5405117..d633b3eaf34c 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -26,9 +26,11 @@
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Pipe.h"
#include "lldb/Host/Socket.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Target/Process.h"
+#include "llvm/ADT/SmallString.h"
// Project includes
#include "ProcessGDBRemoteLog.h"
@@ -756,13 +758,14 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
}
// use native registers, not the GDB registers
- debugserver_args.AppendArgument("--native-regs");
- // make debugserver run in its own session so signals generated by
- // special terminal key sequences (^C) don't affect debugserver
- debugserver_args.AppendArgument("--setsid");
+ debugserver_args.AppendArgument("--native-regs");
- char named_pipe_path[PATH_MAX];
- named_pipe_path[0] = '\0';
+ if (launch_info.GetLaunchInSeparateProcessGroup())
+ {
+ debugserver_args.AppendArgument("--setsid");
+ }
+
+ llvm::SmallString<PATH_MAX> named_pipe_path;
Pipe port_named_pipe;
bool listen = false;
@@ -776,25 +779,11 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
{
// Binding to port zero, we need to figure out what port it ends up
// using using a named pipe...
- FileSpec tmpdir_file_spec;
- if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
- {
- tmpdir_file_spec.AppendPathComponent("debugserver-named-pipe.XXXXXX");
- strncpy(named_pipe_path, tmpdir_file_spec.GetPath().c_str(), sizeof(named_pipe_path));
- }
- else
- {
- strncpy(named_pipe_path, "/tmp/debugserver-named-pipe.XXXXXX", sizeof(named_pipe_path));
- }
-
- if (::mktemp (named_pipe_path))
- {
- error = port_named_pipe.CreateNew(named_pipe_path, false);
- if (error.Fail())
- return error;
- debugserver_args.AppendArgument("--named-pipe");
- debugserver_args.AppendArgument(named_pipe_path);
- }
+ error = port_named_pipe.CreateWithUniqueName("debugserver-named-pipe", false, named_pipe_path);
+ if (error.Fail())
+ return error;
+ debugserver_args.AppendArgument("--named-pipe");
+ debugserver_args.AppendArgument(named_pipe_path.c_str());
}
else
{
@@ -874,7 +863,7 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
if (error.Success() && launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
{
- if (named_pipe_path[0])
+ if (named_pipe_path.size() > 0)
{
error = port_named_pipe.OpenAsReader(named_pipe_path, false);
if (error.Success())
@@ -887,14 +876,14 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
if (error.Success())
{
assert (num_bytes > 0 && port_cstr[num_bytes-1] == '\0');
- out_port = Args::StringToUInt32(port_cstr, 0);
+ out_port = StringConvert::ToUInt32(port_cstr, 0);
if (log)
log->Printf("GDBRemoteCommunication::%s() debugserver listens %u port", __FUNCTION__, out_port);
}
else
{
if (log)
- log->Printf("GDBRemoteCommunication::%s() failed to read a port value from named pipe %s: %s", __FUNCTION__, named_pipe_path, error.AsCString());
+ log->Printf("GDBRemoteCommunication::%s() failed to read a port value from named pipe %s: %s", __FUNCTION__, named_pipe_path.c_str(), error.AsCString());
}
port_named_pipe.Close();
@@ -902,13 +891,13 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
else
{
if (log)
- log->Printf("GDBRemoteCommunication::%s() failed to open named pipe %s for reading: %s", __FUNCTION__, named_pipe_path, error.AsCString());
+ log->Printf("GDBRemoteCommunication::%s() failed to open named pipe %s for reading: %s", __FUNCTION__, named_pipe_path.c_str(), error.AsCString());
}
const auto err = port_named_pipe.Delete(named_pipe_path);
if (err.Fail())
{
if (log)
- log->Printf ("GDBRemoteCommunication::%s failed to delete pipe %s: %s", __FUNCTION__, named_pipe_path, err.AsCString());
+ log->Printf ("GDBRemoteCommunication::%s failed to delete pipe %s: %s", __FUNCTION__, named_pipe_path.c_str(), err.AsCString());
}
}
else if (listen)
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index ac203a62788a..ee2f3276513d 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -27,6 +27,16 @@
#include "Utility/StringExtractorGDBRemote.h"
+typedef enum
+{
+ eStoppointInvalid = -1,
+ eBreakpointSoftware = 0,
+ eBreakpointHardware,
+ eWatchpointWrite,
+ eWatchpointRead,
+ eWatchpointReadWrite
+} GDBStoppointType;
+
class ProcessGDBRemote;
class GDBRemoteCommunication : public lldb_private::Communication
@@ -282,9 +292,8 @@ protected:
ListenThread (lldb::thread_arg_t arg);
private:
- lldb_private::HostThread m_listen_thread;
+ lldb_private::HostThread m_listen_thread;
std::string m_listen_url;
-
//------------------------------------------------------------------
// For GDBRemoteCommunication only
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 52750de5a25f..0f99688fc823 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -28,6 +28,7 @@
#include "lldb/Host/Endian.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Target/Target.h"
@@ -1210,13 +1211,13 @@ GDBRemoteCommunicationClient::SendInterrupt
}
lldb::pid_t
-GDBRemoteCommunicationClient::GetCurrentProcessID ()
+GDBRemoteCommunicationClient::GetCurrentProcessID (bool allow_lazy)
{
- if (m_curr_pid_is_valid == eLazyBoolYes)
+ if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
return m_curr_pid;
// First try to retrieve the pid via the qProcessInfo request.
- GetCurrentProcessInfo ();
+ GetCurrentProcessInfo (allow_lazy);
if (m_curr_pid_is_valid == eLazyBoolYes)
{
// We really got it.
@@ -1559,7 +1560,7 @@ GDBRemoteCommunicationClient::GetGDBServerVersion()
size_t dot_pos = value.find('.');
if (dot_pos != std::string::npos)
value[dot_pos] = '\0';
- const uint32_t version = Args::StringToUInt32(value.c_str(), UINT32_MAX, 0);
+ const uint32_t version = StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0);
if (version != UINT32_MAX)
{
success = true;
@@ -1625,14 +1626,14 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)
if (name.compare("cputype") == 0)
{
// exception type in big endian hex
- cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
+ cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
if (cpu != LLDB_INVALID_CPUTYPE)
++num_keys_decoded;
}
else if (name.compare("cpusubtype") == 0)
{
// exception count in big endian hex
- sub = Args::StringToUInt32 (value.c_str(), 0, 0);
+ sub = StringConvert::ToUInt32 (value.c_str(), 0, 0);
if (sub != 0)
++num_keys_decoded;
}
@@ -1700,7 +1701,7 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)
}
else if (name.compare("ptrsize") == 0)
{
- pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
+ pointer_byte_size = StringConvert::ToUInt32 (value.c_str(), 0, 0);
if (pointer_byte_size != 0)
++num_keys_decoded;
}
@@ -1725,7 +1726,7 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)
}
else if (name.compare("default_packet_timeout") == 0)
{
- m_default_packet_timeout = Args::StringToUInt32(value.c_str(), 0);
+ m_default_packet_timeout = StringConvert::ToUInt32(value.c_str(), 0);
if (m_default_packet_timeout > 0)
{
SetPacketTimeout(m_default_packet_timeout);
@@ -1865,6 +1866,21 @@ GDBRemoteCommunicationClient::SendAttach
return -1;
}
+int
+GDBRemoteCommunicationClient::SendStdinNotification (const char* data, size_t data_len)
+{
+ StreamString packet;
+ packet.PutCString("I");
+ packet.PutBytesAsRawHex8(data, data_len);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
+ {
+ return 0;
+ }
+ return response.GetError();
+
+}
+
const lldb_private::ArchSpec &
GDBRemoteCommunicationClient::GetHostArchitecture ()
{
@@ -2006,13 +2022,13 @@ GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
{
if (name.compare ("start") == 0)
{
- addr_value = Args::StringToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success);
+ addr_value = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success);
if (success)
region_info.GetRange().SetRangeBase(addr_value);
}
else if (name.compare ("size") == 0)
{
- addr_value = Args::StringToUInt64(value.c_str(), 0, 16, &success);
+ addr_value = StringConvert::ToUInt64(value.c_str(), 0, 16, &success);
if (success)
region_info.GetRange().SetByteSize (addr_value);
}
@@ -2107,7 +2123,7 @@ GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num)
{
if (name.compare ("num") == 0)
{
- num = Args::StringToUInt32(value.c_str(), 0, 0);
+ num = StringConvert::ToUInt32(value.c_str(), 0, 0);
m_num_supported_hardware_watchpoints = num;
}
}
@@ -2309,27 +2325,27 @@ GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemot
{
if (name.compare("pid") == 0)
{
- process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
+ process_info.SetProcessID (StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
}
else if (name.compare("ppid") == 0)
{
- process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
+ process_info.SetParentProcessID (StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
}
else if (name.compare("uid") == 0)
{
- process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
+ process_info.SetUserID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
}
else if (name.compare("euid") == 0)
{
- process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
+ process_info.SetEffectiveUserID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
}
else if (name.compare("gid") == 0)
{
- process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
+ process_info.SetGroupID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
}
else if (name.compare("egid") == 0)
{
- process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
+ process_info.SetEffectiveGroupID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
}
else if (name.compare("triple") == 0)
{
@@ -2351,11 +2367,11 @@ GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemot
}
else if (name.compare("cputype") == 0)
{
- cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
+ cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
}
else if (name.compare("cpusubtype") == 0)
{
- sub = Args::StringToUInt32 (value.c_str(), 0, 16);
+ sub = StringConvert::ToUInt32 (value.c_str(), 0, 16);
}
else if (name.compare("vendor") == 0)
{
@@ -2408,14 +2424,17 @@ GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceIn
}
bool
-GDBRemoteCommunicationClient::GetCurrentProcessInfo ()
+GDBRemoteCommunicationClient::GetCurrentProcessInfo (bool allow_lazy)
{
Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
- if (m_qProcessInfo_is_valid == eLazyBoolYes)
- return true;
- if (m_qProcessInfo_is_valid == eLazyBoolNo)
- return false;
+ if (allow_lazy)
+ {
+ if (m_qProcessInfo_is_valid == eLazyBoolYes)
+ return true;
+ if (m_qProcessInfo_is_valid == eLazyBoolNo)
+ return false;
+ }
GetHostInfo ();
@@ -2441,13 +2460,13 @@ GDBRemoteCommunicationClient::GetCurrentProcessInfo ()
{
if (name.compare("cputype") == 0)
{
- cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
+ cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
if (cpu != LLDB_INVALID_CPUTYPE)
++num_keys_decoded;
}
else if (name.compare("cpusubtype") == 0)
{
- sub = Args::StringToUInt32 (value.c_str(), 0, 16);
+ sub = StringConvert::ToUInt32 (value.c_str(), 0, 16);
if (sub != 0)
++num_keys_decoded;
}
@@ -2483,13 +2502,13 @@ GDBRemoteCommunicationClient::GetCurrentProcessInfo ()
}
else if (name.compare("ptrsize") == 0)
{
- pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 16);
+ pointer_byte_size = StringConvert::ToUInt32 (value.c_str(), 0, 16);
if (pointer_byte_size != 0)
++num_keys_decoded;
}
else if (name.compare("pid") == 0)
{
- pid = Args::StringToUInt64(value.c_str(), 0, 16);
+ pid = StringConvert::ToUInt64(value.c_str(), 0, 16);
if (pid != LLDB_INVALID_PROCESS_ID)
++num_keys_decoded;
}
@@ -2849,7 +2868,11 @@ GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort (lldb::pid_t &pid, const
const char *packet = stream.GetData();
int packet_len = stream.GetSize();
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
+ // give the process a few seconds to startup
+ const uint32_t old_packet_timeout = SetPacketTimeout (10);
+ auto result = SendPacketAndWaitForResponse(packet, packet_len, response, false);
+ SetPacketTimeout (old_packet_timeout);
+ if (result == PacketResult::Success)
{
std::string name;
std::string value;
@@ -2857,9 +2880,9 @@ GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort (lldb::pid_t &pid, const
while (response.GetNameColonValue(name, value))
{
if (name.compare("port") == 0)
- port = Args::StringToUInt32(value.c_str(), 0, 0);
+ port = StringConvert::ToUInt32(value.c_str(), 0, 0);
else if (name.compare("pid") == 0)
- pid = Args::StringToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
+ pid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
}
return port;
}
@@ -3013,6 +3036,7 @@ GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type,
case eWatchpointWrite: m_supports_z2 = false; break;
case eWatchpointRead: m_supports_z3 = false; break;
case eWatchpointReadWrite: m_supports_z4 = false; break;
+ case eStoppointInvalid: return UINT8_MAX;
}
}
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index fddcd6cd1426..d90614bce88b 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -21,15 +21,6 @@
#include "GDBRemoteCommunication.h"
-typedef enum
-{
- eBreakpointSoftware = 0,
- eBreakpointHardware,
- eWatchpointWrite,
- eWatchpointRead,
- eWatchpointReadWrite
-} GDBStoppointType;
-
class GDBRemoteCommunicationClient : public GDBRemoteCommunication
{
public:
@@ -109,7 +100,7 @@ public:
bool &timed_out);
lldb::pid_t
- GetCurrentProcessID ();
+ GetCurrentProcessID (bool allow_lazy = true);
bool
GetLaunchSuccess (std::string &error_str);
@@ -184,6 +175,23 @@ public:
//------------------------------------------------------------------
+ /// Sends a GDB remote protocol 'I' packet that delivers stdin
+ /// data to the remote process.
+ ///
+ /// @param[in] data
+ /// A pointer to stdin data.
+ ///
+ /// @param[in] data_len
+ /// The number of bytes available at \a data.
+ ///
+ /// @return
+ /// Zero if the attach was successful, or an error indicating
+ /// an error code.
+ //------------------------------------------------------------------
+ int
+ SendStdinNotification(const char* data, size_t data_len);
+
+ //------------------------------------------------------------------
/// Sets the path to use for stdin/out/err for a process
/// that will be launched with the 'A' packet.
///
@@ -375,8 +383,8 @@ public:
case eWatchpointWrite: return m_supports_z2;
case eWatchpointRead: return m_supports_z3;
case eWatchpointReadWrite: return m_supports_z4;
+ case eStoppointInvalid: return false;
}
- return false;
}
uint8_t
SendGDBStoppointTypePacket (GDBStoppointType type, // Type of breakpoint or watchpoint
@@ -534,7 +542,7 @@ protected:
StringExtractorGDBRemote &response);
bool
- GetCurrentProcessInfo ();
+ GetCurrentProcessInfo (bool allow_lazy_pid = true);
bool
GetGDBServerVersion();
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index a7149505e869..dd920c0df0ca 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -34,16 +34,18 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Target/FileAction.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
-#include "lldb/Target/NativeRegisterContext.h"
-#include "Host/common/NativeProcessProtocol.h"
-#include "Host/common/NativeThreadProtocol.h"
+#include "lldb/Host/common/NativeRegisterContext.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Host/common/NativeThreadProtocol.h"
// Project includes
#include "Utility/StringExtractorGDBRemote.h"
+#include "Utility/UriParser.h"
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
@@ -276,6 +278,10 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec,
packet_result = Handle_qPlatform_shell (packet);
break;
+ case StringExtractorGDBRemote::eServerPacketType_qWatchpointSupportInfo:
+ packet_result = Handle_qWatchpointSupportInfo (packet);
+ break;
+
case StringExtractorGDBRemote::eServerPacketType_C:
packet_result = Handle_C (packet);
break;
@@ -364,6 +370,10 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec,
packet_result = Handle_H (packet);
break;
+ case StringExtractorGDBRemote::eServerPacketType_I:
+ packet_result = Handle_I (packet);
+ break;
+
case StringExtractorGDBRemote::eServerPacketType_m:
packet_result = Handle_m (packet);
break;
@@ -601,14 +611,12 @@ GDBRemoteCommunicationServer::LaunchPlatformProcess ()
// add to list of spawned processes. On an lldb-gdbserver, we
// would expect there to be only one.
- lldb::pid_t pid;
- if ( (pid = m_process_launch_info.GetProcessID()) != LLDB_INVALID_PROCESS_ID )
+ const auto pid = m_process_launch_info.GetProcessID();
+ if (pid != LLDB_INVALID_PROCESS_ID)
{
// add to spawned pids
- {
- Mutex::Locker locker (m_spawned_pids_mutex);
- m_spawned_pids.insert(pid);
- }
+ Mutex::Locker locker (m_spawned_pids_mutex);
+ m_spawned_pids.insert(pid);
}
return error;
@@ -835,12 +843,12 @@ GDBRemoteCommunicationServer::SendStopReplyPacketForThread (lldb::tid_t tid)
// Grab the reason this thread stopped.
struct ThreadStopInfo tid_stop_info;
- if (!thread_sp->GetStopReason (tid_stop_info))
+ std::string description;
+ if (!thread_sp->GetStopReason (tid_stop_info, description))
return SendErrorResponse (52);
- const bool did_exec = tid_stop_info.reason == eStopReasonExec;
// FIXME implement register handling for exec'd inferiors.
- // if (did_exec)
+ // if (tid_stop_info.reason == eStopReasonExec)
// {
// const bool force = true;
// InitializeRegisters(force);
@@ -861,25 +869,6 @@ GDBRemoteCommunicationServer::SendStopReplyPacketForThread (lldb::tid_t tid)
tid_stop_info.details.exception.type);
}
- switch (tid_stop_info.reason)
- {
- case eStopReasonSignal:
- case eStopReasonException:
- signum = thread_sp->TranslateStopInfoToGdbSignal (tid_stop_info);
- break;
- default:
- signum = 0;
- if (log)
- {
- log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64 " tid %" PRIu64 " has stop reason %d, using signo = 0 in stop reply response",
- __FUNCTION__,
- m_debugged_process_sp->GetID (),
- tid,
- tid_stop_info.reason);
- }
- break;
- }
-
// Print the signal number.
response.PutHex8 (signum & 0xff);
@@ -906,14 +895,6 @@ GDBRemoteCommunicationServer::SendStopReplyPacketForThread (lldb::tid_t tid)
response.PutChar (';');
}
- // FIXME look for analog
- // thread_identifier_info_data_t thread_ident_info;
- // if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info))
- // {
- // if (thread_ident_info.dispatch_qaddr != 0)
- // ostrm << std::hex << "qaddr:" << thread_ident_info.dispatch_qaddr << ';';
- // }
-
// If a 'QListThreadsInStopReply' was sent to enable this feature, we
// will send all thread IDs back in the "threads" key whose value is
// a list of hex thread IDs separated by commas:
@@ -978,9 +959,45 @@ GDBRemoteCommunicationServer::SendStopReplyPacketForThread (lldb::tid_t tid)
}
}
- if (did_exec)
+ const char* reason_str = nullptr;
+ switch (tid_stop_info.reason)
+ {
+ case eStopReasonTrace:
+ reason_str = "trace";
+ break;
+ case eStopReasonBreakpoint:
+ reason_str = "breakpoint";
+ break;
+ case eStopReasonWatchpoint:
+ reason_str = "watchpoint";
+ break;
+ case eStopReasonSignal:
+ reason_str = "signal";
+ break;
+ case eStopReasonException:
+ reason_str = "exception";
+ break;
+ case eStopReasonExec:
+ reason_str = "exec";
+ break;
+ case eStopReasonInstrumentation:
+ case eStopReasonInvalid:
+ case eStopReasonPlanComplete:
+ case eStopReasonThreadExiting:
+ case eStopReasonNone:
+ break;
+ }
+ if (reason_str != nullptr)
+ {
+ response.Printf ("reason:%s;", reason_str);
+ }
+
+ if (!description.empty())
{
- response.PutCString ("reason:exec;");
+ // Description may contains special chars, send as hex bytes.
+ response.PutCString ("description:");
+ response.PutCStringAsRawHex8 (description.c_str ());
+ response.PutChar (';');
}
else if ((tid_stop_info.reason == eStopReasonException) && tid_stop_info.details.exception.type)
{
@@ -1422,23 +1439,34 @@ CreateProcessInfoResponse_DebugServerStyle (const ProcessInstanceInfo &proc_info
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_qProcessInfo (StringExtractorGDBRemote &packet)
{
- // Only the gdb server handles this.
- if (!IsGdbServer ())
- return SendUnimplementedResponse (packet.GetStringRef ().c_str ());
-
- // Fail if we don't have a current process.
- if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
- return SendErrorResponse (68);
-
- ProcessInstanceInfo proc_info;
- if (Host::GetProcessInfo (m_debugged_process_sp->GetID (), proc_info))
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+
+ if (IsGdbServer ())
{
- StreamString response;
- CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
- return SendPacketNoLock (response.GetData (), response.GetSize ());
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse (68);
+
+ pid = m_debugged_process_sp->GetID ();
}
-
- return SendErrorResponse (1);
+ else if (m_is_platform)
+ {
+ pid = m_process_launch_info.GetProcessID ();
+ m_process_launch_info.Clear ();
+ }
+ else
+ return SendUnimplementedResponse (packet.GetStringRef ().c_str ());
+
+ if (pid == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse (1);
+
+ ProcessInstanceInfo proc_info;
+ if (!Host::GetProcessInfo (pid, proc_info))
+ return SendErrorResponse (1);
+
+ StreamString response;
+ CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
+ return SendPacketNoLock (response.GetData (), response.GetSize ());
}
GDBRemoteCommunication::PacketResult
@@ -1512,27 +1540,27 @@ GDBRemoteCommunicationServer::Handle_qfProcessInfo (StringExtractorGDBRemote &pa
}
else if (key.compare("pid") == 0)
{
- match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
+ match_info.GetProcessInfo().SetProcessID (StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
}
else if (key.compare("parent_pid") == 0)
{
- match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
+ match_info.GetProcessInfo().SetParentProcessID (StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
}
else if (key.compare("uid") == 0)
{
- match_info.GetProcessInfo().SetUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
+ match_info.GetProcessInfo().SetUserID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
}
else if (key.compare("gid") == 0)
{
- match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
+ match_info.GetProcessInfo().SetGroupID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
}
else if (key.compare("euid") == 0)
{
- match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
+ match_info.GetProcessInfo().SetEffectiveUserID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
}
else if (key.compare("egid") == 0)
{
- match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
+ match_info.GetProcessInfo().SetEffectiveGroupID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success));
}
else if (key.compare("all_users") == 0)
{
@@ -1627,7 +1655,7 @@ GDBRemoteCommunicationServer::Handle_qSpeedTest (StringExtractorGDBRemote &packe
bool success = packet.GetNameColonValue(key, value);
if (success && key.compare("response_size") == 0)
{
- uint32_t response_size = Args::StringToUInt32(value.c_str(), 0, 0, &success);
+ uint32_t response_size = StringConvert::ToUInt32(value.c_str(), 0, 0, &success);
if (success)
{
if (response_size == 0)
@@ -1901,7 +1929,7 @@ GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote
if (name.compare ("host") == 0)
hostname.swap(value);
else if (name.compare ("port") == 0)
- port = Args::StringToUInt32(value.c_str(), 0, 0);
+ port = StringConvert::ToUInt32(value.c_str(), 0, 0);
}
if (port == UINT16_MAX)
port = GetNextAvailablePort();
@@ -1909,6 +1937,9 @@ GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote
// Spawn a new thread to accept the port that gets bound after
// binding to port 0 (zero).
+ // ignore the hostname send from the remote end, just use the ip address
+ // that we're currently communicating with as the hostname
+
// Spawn a debugserver and try to get the port it listens to.
ProcessLaunchInfo debugserver_launch_info;
if (hostname.empty())
@@ -1916,9 +1947,19 @@ GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote
if (log)
log->Printf("Launching debugserver with: %s:%u...\n", hostname.c_str(), port);
+ // Do not run in a new session so that it can not linger after the
+ // platform closes.
+ debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
- Error error = StartDebugserverProcess (hostname.empty() ? NULL : hostname.c_str(),
+ std::string platform_scheme;
+ std::string platform_ip;
+ int platform_port;
+ std::string platform_path;
+ bool ok = UriParser::Parse(GetConnection()->GetURI().c_str(), platform_scheme, platform_ip, platform_port, platform_path);
+ assert(ok);
+ Error error = StartDebugserverProcess (
+ platform_ip.c_str(),
port,
debugserver_launch_info,
port);
@@ -2502,10 +2543,6 @@ GDBRemoteCommunicationServer::Handle_vCont (StringExtractorGDBRemote &packet)
thread_actions.Append (thread_action);
}
- // If a default action for all other threads wasn't mentioned
- // then we should stop the threads.
- thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
-
Error error = m_debugged_process_sp->Resume (thread_actions);
if (error.Fail ())
{
@@ -2983,7 +3020,7 @@ GDBRemoteCommunicationServer::Handle_qRegisterInfo (StringExtractorGDBRemote &pa
return SendErrorResponse (69);
// Return the end of registers response if we've iterated one past the end of the register set.
- if (reg_index >= reg_context_sp->GetRegisterCount ())
+ if (reg_index >= reg_context_sp->GetUserRegisterCount ())
return SendErrorResponse (69);
const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex(reg_index);
@@ -3184,10 +3221,10 @@ GDBRemoteCommunicationServer::Handle_p (StringExtractorGDBRemote &packet)
}
// Return the end of registers response if we've iterated one past the end of the register set.
- if (reg_index >= reg_context_sp->GetRegisterCount ())
+ if (reg_index >= reg_context_sp->GetUserRegisterCount ())
{
if (log)
- log->Printf ("GDBRemoteCommunicationServer::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetRegisterCount ());
+ log->Printf ("GDBRemoteCommunicationServer::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetUserRegisterCount ());
return SendErrorResponse (0x15);
}
@@ -3264,7 +3301,8 @@ GDBRemoteCommunicationServer::Handle_P (StringExtractorGDBRemote &packet)
}
// Parse out the value.
- const uint64_t raw_value = packet.GetHexMaxU64 (process_arch.GetByteOrder () == lldb::eByteOrderLittle, std::numeric_limits<uint64_t>::max ());
+ uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register
+ size_t reg_size = packet.GetHexBytesAvail (reg_bytes, sizeof(reg_bytes));
// Get the thread to use.
NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet);
@@ -3284,7 +3322,7 @@ GDBRemoteCommunicationServer::Handle_P (StringExtractorGDBRemote &packet)
return SendErrorResponse (0x15);
}
- const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex (reg_index);
if (!reg_info)
{
if (log)
@@ -3293,20 +3331,23 @@ GDBRemoteCommunicationServer::Handle_P (StringExtractorGDBRemote &packet)
}
// Return the end of registers response if we've iterated one past the end of the register set.
- if (reg_index >= reg_context_sp->GetRegisterCount ())
+ if (reg_index >= reg_context_sp->GetUserRegisterCount ())
{
if (log)
- log->Printf ("GDBRemoteCommunicationServer::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetRegisterCount ());
+ log->Printf ("GDBRemoteCommunicationServer::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetUserRegisterCount ());
return SendErrorResponse (0x47);
}
+ if (reg_size != reg_info->byte_size)
+ {
+ return SendIllFormedResponse (packet, "P packet register size is incorrect");
+ }
// Build the reginfos response.
StreamGDBRemote response;
- // FIXME Could be suffixed with a thread: parameter.
- // That thread then needs to be fed back into the reg context retrieval above.
- Error error = reg_context_sp->WriteRegisterFromUnsigned (reg_info, raw_value);
+ RegisterValue reg_value (reg_bytes, reg_size, process_arch.GetByteOrder ());
+ Error error = reg_context_sp->WriteRegister (reg_info, reg_value);
if (error.Fail ())
{
if (log)
@@ -3394,6 +3435,46 @@ GDBRemoteCommunicationServer::Handle_H (StringExtractorGDBRemote &packet)
}
GDBRemoteCommunicationServer::PacketResult
+GDBRemoteCommunicationServer::Handle_I (StringExtractorGDBRemote &packet)
+{
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ // Ensure we're llgs.
+ if (!IsGdbServer())
+ return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_I() unimplemented");
+
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
+ {
+ if (log)
+ log->Printf ("GDBRemoteCommunicationServer::%s failed, no process available", __FUNCTION__);
+ return SendErrorResponse (0x15);
+ }
+
+ packet.SetFilePos (::strlen("I"));
+ char tmp[4096];
+ for (;;)
+ {
+ size_t read = packet.GetHexBytesAvail(tmp, sizeof(tmp));
+ if (read == 0)
+ {
+ break;
+ }
+ // write directly to stdin *this might block if stdin buffer is full*
+ // TODO: enqueue this block in circular buffer and send window size to remote host
+ ConnectionStatus status;
+ Error error;
+ m_stdio_communication.Write(tmp, read, status, &error);
+ if (error.Fail())
+ {
+ return SendErrorResponse (0x15);
+ }
+ }
+
+ return SendOKResponse();
+}
+
+GDBRemoteCommunicationServer::PacketResult
GDBRemoteCommunicationServer::Handle_interrupt (StringExtractorGDBRemote &packet)
{
Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
@@ -3704,8 +3785,6 @@ GDBRemoteCommunicationServer::Handle_qMemoryRegionInfo (StringExtractorGDBRemote
GDBRemoteCommunicationServer::PacketResult
GDBRemoteCommunicationServer::Handle_Z (StringExtractorGDBRemote &packet)
{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
-
// We don't support if we're not llgs.
if (!IsGdbServer())
return SendUnimplementedResponse ("");
@@ -3713,12 +3792,13 @@ GDBRemoteCommunicationServer::Handle_Z (StringExtractorGDBRemote &packet)
// Ensure we have a process.
if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
{
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
if (log)
log->Printf ("GDBRemoteCommunicationServer::%s failed, no process available", __FUNCTION__);
return SendErrorResponse (0x15);
}
- // Parse out software or hardware breakpoint requested.
+ // Parse out software or hardware breakpoint or watchpoint requested.
packet.SetFilePos (strlen("Z"));
if (packet.GetBytesLeft() < 1)
return SendIllFormedResponse(packet, "Too short Z packet, missing software/hardware specifier");
@@ -3726,61 +3806,82 @@ GDBRemoteCommunicationServer::Handle_Z (StringExtractorGDBRemote &packet)
bool want_breakpoint = true;
bool want_hardware = false;
- const char breakpoint_type_char = packet.GetChar ();
- switch (breakpoint_type_char)
- {
- case '0': want_hardware = false; want_breakpoint = true; break;
- case '1': want_hardware = true; want_breakpoint = true; break;
- case '2': want_breakpoint = false; break;
- case '3': want_breakpoint = false; break;
- default:
+ const GDBStoppointType stoppoint_type =
+ GDBStoppointType(packet.GetS32 (eStoppointInvalid));
+ switch (stoppoint_type)
+ {
+ case eBreakpointSoftware:
+ want_hardware = false; want_breakpoint = true; break;
+ case eBreakpointHardware:
+ want_hardware = true; want_breakpoint = true; break;
+ case eWatchpointWrite:
+ want_hardware = true; want_breakpoint = false; break;
+ case eWatchpointRead:
+ want_hardware = true; want_breakpoint = false; break;
+ case eWatchpointReadWrite:
+ want_hardware = true; want_breakpoint = false; break;
+ case eStoppointInvalid:
return SendIllFormedResponse(packet, "Z packet had invalid software/hardware specifier");
}
if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
- return SendIllFormedResponse(packet, "Malformed Z packet, expecting comma after breakpoint type");
+ return SendIllFormedResponse(packet, "Malformed Z packet, expecting comma after stoppoint type");
- // FIXME implement watchpoint support.
- if (!want_breakpoint)
- return SendUnimplementedResponse ("watchpoint support not yet implemented");
-
- // Parse out the breakpoint address.
+ // Parse out the stoppoint address.
if (packet.GetBytesLeft() < 1)
return SendIllFormedResponse(packet, "Too short Z packet, missing address");
- const lldb::addr_t breakpoint_addr = packet.GetHexMaxU64(false, 0);
+ const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
return SendIllFormedResponse(packet, "Malformed Z packet, expecting comma after address");
- // Parse out the breakpoint kind (i.e. size hint for opcode size).
- const uint32_t kind = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
- if (kind == std::numeric_limits<uint32_t>::max ())
- return SendIllFormedResponse(packet, "Malformed Z packet, failed to parse kind argument");
+ // Parse out the stoppoint size (i.e. size hint for opcode size).
+ const uint32_t size = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
+ if (size == std::numeric_limits<uint32_t>::max ())
+ return SendIllFormedResponse(packet, "Malformed Z packet, failed to parse size argument");
if (want_breakpoint)
{
// Try to set the breakpoint.
- const Error error = m_debugged_process_sp->SetBreakpoint (breakpoint_addr, kind, want_hardware);
+ const Error error = m_debugged_process_sp->SetBreakpoint (addr, size, want_hardware);
if (error.Success ())
return SendOKResponse ();
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64 " failed to set breakpoint: %s", __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ());
- return SendErrorResponse (0x09);
- }
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64
+ " failed to set breakpoint: %s",
+ __FUNCTION__,
+ m_debugged_process_sp->GetID (),
+ error.AsCString ());
+ return SendErrorResponse (0x09);
}
+ else
+ {
+ uint32_t watch_flags =
+ stoppoint_type == eWatchpointWrite
+ ? watch_flags = 0x1 // Write
+ : watch_flags = 0x3; // ReadWrite
- // FIXME fix up after watchpoints are handled.
- return SendUnimplementedResponse ("");
+ // Try to set the watchpoint.
+ const Error error = m_debugged_process_sp->SetWatchpoint (
+ addr, size, watch_flags, want_hardware);
+ if (error.Success ())
+ return SendOKResponse ();
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64
+ " failed to set watchpoint: %s",
+ __FUNCTION__,
+ m_debugged_process_sp->GetID (),
+ error.AsCString ());
+ return SendErrorResponse (0x09);
+ }
}
GDBRemoteCommunicationServer::PacketResult
GDBRemoteCommunicationServer::Handle_z (StringExtractorGDBRemote &packet)
{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
-
// We don't support if we're not llgs.
if (!IsGdbServer())
return SendUnimplementedResponse ("");
@@ -3788,66 +3889,81 @@ GDBRemoteCommunicationServer::Handle_z (StringExtractorGDBRemote &packet)
// Ensure we have a process.
if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
{
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
if (log)
log->Printf ("GDBRemoteCommunicationServer::%s failed, no process available", __FUNCTION__);
return SendErrorResponse (0x15);
}
- // Parse out software or hardware breakpoint requested.
+ // Parse out software or hardware breakpoint or watchpoint requested.
packet.SetFilePos (strlen("z"));
if (packet.GetBytesLeft() < 1)
return SendIllFormedResponse(packet, "Too short z packet, missing software/hardware specifier");
bool want_breakpoint = true;
- const char breakpoint_type_char = packet.GetChar ();
- switch (breakpoint_type_char)
+ const GDBStoppointType stoppoint_type =
+ GDBStoppointType(packet.GetS32 (eStoppointInvalid));
+ switch (stoppoint_type)
{
- case '0': want_breakpoint = true; break;
- case '1': want_breakpoint = true; break;
- case '2': want_breakpoint = false; break;
- case '3': want_breakpoint = false; break;
+ case eBreakpointHardware: want_breakpoint = true; break;
+ case eBreakpointSoftware: want_breakpoint = true; break;
+ case eWatchpointWrite: want_breakpoint = false; break;
+ case eWatchpointRead: want_breakpoint = false; break;
+ case eWatchpointReadWrite: want_breakpoint = false; break;
default:
return SendIllFormedResponse(packet, "z packet had invalid software/hardware specifier");
}
if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
- return SendIllFormedResponse(packet, "Malformed z packet, expecting comma after breakpoint type");
-
- // FIXME implement watchpoint support.
- if (!want_breakpoint)
- return SendUnimplementedResponse ("watchpoint support not yet implemented");
+ return SendIllFormedResponse(packet, "Malformed z packet, expecting comma after stoppoint type");
- // Parse out the breakpoint address.
+ // Parse out the stoppoint address.
if (packet.GetBytesLeft() < 1)
return SendIllFormedResponse(packet, "Too short z packet, missing address");
- const lldb::addr_t breakpoint_addr = packet.GetHexMaxU64(false, 0);
+ const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
return SendIllFormedResponse(packet, "Malformed z packet, expecting comma after address");
- // Parse out the breakpoint kind (i.e. size hint for opcode size).
- const uint32_t kind = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
- if (kind == std::numeric_limits<uint32_t>::max ())
- return SendIllFormedResponse(packet, "Malformed z packet, failed to parse kind argument");
+ /*
+ // Parse out the stoppoint size (i.e. size hint for opcode size).
+ const uint32_t size = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
+ if (size == std::numeric_limits<uint32_t>::max ())
+ return SendIllFormedResponse(packet, "Malformed z packet, failed to parse size argument");
+ */
if (want_breakpoint)
{
// Try to clear the breakpoint.
- const Error error = m_debugged_process_sp->RemoveBreakpoint (breakpoint_addr);
+ const Error error = m_debugged_process_sp->RemoveBreakpoint (addr);
if (error.Success ())
return SendOKResponse ();
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64 " failed to remove breakpoint: %s", __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ());
- return SendErrorResponse (0x09);
- }
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ if (log)
+ log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64
+ " failed to remove breakpoint: %s",
+ __FUNCTION__,
+ m_debugged_process_sp->GetID (),
+ error.AsCString ());
+ return SendErrorResponse (0x09);
+ }
+ else
+ {
+ // Try to clear the watchpoint.
+ const Error error = m_debugged_process_sp->RemoveWatchpoint (addr);
+ if (error.Success ())
+ return SendOKResponse ();
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64
+ " failed to remove watchpoint: %s",
+ __FUNCTION__,
+ m_debugged_process_sp->GetID (),
+ error.AsCString ());
+ return SendErrorResponse (0x09);
}
-
- // FIXME fix up after watchpoints are handled.
- return SendUnimplementedResponse ("");
}
GDBRemoteCommunicationServer::PacketResult
@@ -4283,6 +4399,30 @@ GDBRemoteCommunicationServer::Handle_qThreadStopInfo (StringExtractorGDBRemote &
return SendStopReplyPacketForThread (tid);
}
+GDBRemoteCommunicationServer::PacketResult
+GDBRemoteCommunicationServer::Handle_qWatchpointSupportInfo (StringExtractorGDBRemote &packet)
+{
+ // Only the gdb server handles this.
+ if (!IsGdbServer ())
+ return SendUnimplementedResponse (packet.GetStringRef ().c_str ());
+
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)
+ return SendErrorResponse (68);
+
+ packet.SetFilePos(strlen("qWatchpointSupportInfo"));
+ if (packet.GetBytesLeft() == 0)
+ return SendOKResponse();
+ if (packet.GetChar() != ':')
+ return SendErrorResponse(67);
+
+ uint32_t num = m_debugged_process_sp->GetMaxWatchpoints();
+ StreamGDBRemote response;
+ response.Printf ("num:%d;", num);
+ return SendPacketNoLock(response.GetData(), response.GetSize());
+}
+
void
GDBRemoteCommunicationServer::FlushInferiorOutput ()
{
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 07ce98e29ac6..dcf07844527e 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -23,7 +23,7 @@
#include "lldb/Target/Process.h"
#include "GDBRemoteCommunication.h"
-#include "../../../Host/common/NativeProcessProtocol.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
class ProcessGDBRemote;
class StringExtractorGDBRemote;
@@ -415,6 +415,9 @@ protected:
Handle_H (StringExtractorGDBRemote &packet);
PacketResult
+ Handle_I (StringExtractorGDBRemote &packet);
+
+ PacketResult
Handle_interrupt (StringExtractorGDBRemote &packet);
PacketResult
@@ -465,6 +468,9 @@ protected:
PacketResult
Handle_qThreadStopInfo (StringExtractorGDBRemote &packet);
+ PacketResult
+ Handle_qWatchpointSupportInfo (StringExtractorGDBRemote &packet);
+
void
SetCurrentThreadID (lldb::tid_t tid);
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index fe99706969c8..cb0b4bb51007 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -42,6 +42,7 @@
#include "lldb/Core/Timer.h"
#include "lldb/Core/Value.h"
#include "lldb/Host/HostThread.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/TimeValue.h"
@@ -431,11 +432,11 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
}
else if (name.compare("bitsize") == 0)
{
- reg_info.byte_size = Args::StringToUInt32(value.c_str(), 0, 0) / CHAR_BIT;
+ reg_info.byte_size = StringConvert::ToUInt32(value.c_str(), 0, 0) / CHAR_BIT;
}
else if (name.compare("offset") == 0)
{
- uint32_t offset = Args::StringToUInt32(value.c_str(), UINT32_MAX, 0);
+ uint32_t offset = StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0);
if (reg_offset != offset)
{
reg_offset = offset;
@@ -483,11 +484,11 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
}
else if (name.compare("gcc") == 0)
{
- reg_info.kinds[eRegisterKindGCC] = Args::StringToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
+ reg_info.kinds[eRegisterKindGCC] = StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
}
else if (name.compare("dwarf") == 0)
{
- reg_info.kinds[eRegisterKindDWARF] = Args::StringToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
+ reg_info.kinds[eRegisterKindDWARF] = StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0);
}
else if (name.compare("generic") == 0)
{
@@ -502,7 +503,7 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
value_pair = value_pair.second.split(',');
if (!value_pair.first.empty())
{
- uint32_t reg = Args::StringToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, 16);
+ uint32_t reg = StringConvert::ToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, 16);
if (reg != LLDB_INVALID_REGNUM)
value_regs.push_back (reg);
}
@@ -517,7 +518,7 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
value_pair = value_pair.second.split(',');
if (!value_pair.first.empty())
{
- uint32_t reg = Args::StringToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, 16);
+ uint32_t reg = StringConvert::ToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, 16);
if (reg != LLDB_INVALID_REGNUM)
invalidate_regs.push_back (reg);
}
@@ -941,6 +942,7 @@ ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info)
SetPrivateState (SetThreadStopInfo (m_last_stop_packet));
+ m_stdio_disable = disable_stdio;
if (!disable_stdio)
{
if (pty.GetMasterFileDescriptor() != lldb_utility::PseudoTerminal::invalid_fd)
@@ -972,9 +974,12 @@ ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
{
Error error;
// Only connect if we have a valid connect URL
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
if (connect_url && connect_url[0])
{
+ if (log)
+ log->Printf("ProcessGDBRemote::%s Connecting to %s", __FUNCTION__, connect_url);
std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
if (conn_ap.get())
{
@@ -1656,17 +1661,17 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
if (name.compare("metype") == 0)
{
// exception type in big endian hex
- exc_type = Args::StringToUInt32 (value.c_str(), 0, 16);
+ exc_type = StringConvert::ToUInt32 (value.c_str(), 0, 16);
}
else if (name.compare("medata") == 0)
{
// exception data in big endian hex
- exc_data.push_back(Args::StringToUInt64 (value.c_str(), 0, 16));
+ exc_data.push_back(StringConvert::ToUInt64 (value.c_str(), 0, 16));
}
else if (name.compare("thread") == 0)
{
// thread in big endian hex
- lldb::tid_t tid = Args::StringToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
+ lldb::tid_t tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
// m_thread_list_real does have its own mutex, but we need to
// hold onto the mutex between the call to m_thread_list_real.FindThreadByID(...)
// and the m_thread_list_real.AddThread(...) so it doesn't change on us
@@ -1702,12 +1707,12 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
{
value[comma_pos] = '\0';
// thread in big endian hex
- tid = Args::StringToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
+ tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
if (tid != LLDB_INVALID_THREAD_ID)
m_thread_ids.push_back (tid);
value.erase(0, comma_pos + 1);
}
- tid = Args::StringToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
+ tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
if (tid != LLDB_INVALID_THREAD_ID)
m_thread_ids.push_back (tid);
}
@@ -1726,7 +1731,7 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
}
else if (name.compare("qaddr") == 0)
{
- thread_dispatch_qaddr = Args::StringToUInt64 (value.c_str(), 0, 16);
+ thread_dispatch_qaddr = StringConvert::ToUInt64 (value.c_str(), 0, 16);
}
else if (name.compare("reason") == 0)
{
@@ -1738,7 +1743,8 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
// Swap "value" over into "name_extractor"
desc_extractor.GetStringRef().swap(value);
// Now convert the HEX bytes into a string value
- desc_extractor.GetHexByteString (thread_name);
+ desc_extractor.GetHexByteString (value);
+ description.swap(value);
}
else if (name.size() == 2 && ::isxdigit(name[0]) && ::isxdigit(name[1]))
{
@@ -1747,7 +1753,7 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
// so it won't have to go and read it.
if (gdb_thread)
{
- uint32_t reg = Args::StringToUInt32 (name.c_str(), UINT32_MAX, 16);
+ uint32_t reg = StringConvert::ToUInt32 (name.c_str(), UINT32_MAX, 16);
if (reg != UINT32_MAX)
{
@@ -1839,8 +1845,24 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
}
else if (reason.compare("watchpoint") == 0)
{
- break_id_t watch_id = LLDB_INVALID_WATCH_ID;
- // TODO: locate the watchpoint somehow...
+ StringExtractor desc_extractor(description.c_str());
+ addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
+ uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32);
+ watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
+ if (wp_addr != LLDB_INVALID_ADDRESS)
+ {
+ WatchpointSP wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr);
+ if (wp_sp)
+ {
+ wp_sp->SetHardwareIndex(wp_index);
+ watch_id = wp_sp->GetID();
+ }
+ }
+ if (watch_id == LLDB_INVALID_WATCH_ID)
+ {
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_WATCHPOINTS));
+ if (log) log->Printf ("failed to find watchpoint");
+ }
thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID (*thread_sp, watch_id));
handled = true;
}
@@ -2456,6 +2478,10 @@ ProcessGDBRemote::PutSTDIN (const char *src, size_t src_len, Error &error)
ConnectionStatus status;
m_stdio_communication.Write(src, src_len, status, NULL);
}
+ else if (!m_stdio_disable)
+ {
+ m_gdb_comm.SendStdinNotification(src, src_len);
+ }
return 0;
}
@@ -2760,6 +2786,10 @@ ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info
static FileSpec g_debugserver_file_spec;
ProcessLaunchInfo debugserver_launch_info;
+ // Make debugserver run in its own session so signals generated by
+ // special terminal key sequences (^C) don't affect debugserver.
+ debugserver_launch_info.SetLaunchInSeparateProcessGroup(true);
+
debugserver_launch_info.SetMonitorProcessCallback (MonitorDebugserverProcess, this, false);
debugserver_launch_info.SetUserID(process_info.GetUserID());
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
index 067449a289be..8935f7143e48 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -13,6 +13,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/Timer.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -992,11 +993,11 @@ DWARFCompileUnit::ParseProducerInfo ()
{
std::string str;
if (regex_match.GetMatchAtIndex (producer_cstr, 1, str))
- m_producer_version_major = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
+ m_producer_version_major = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
if (regex_match.GetMatchAtIndex (producer_cstr, 2, str))
- m_producer_version_minor = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
+ m_producer_version_minor = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
if (regex_match.GetMatchAtIndex (producer_cstr, 3, str))
- m_producer_version_update = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
+ m_producer_version_update = StringConvert::ToUInt32(str.c_str(), UINT32_MAX, 10);
}
m_producer = eProducerClang;
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 10b51ffe0a8a..6a8c4e6d57b9 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -2294,22 +2294,26 @@ DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data,
if (dwarf2Data)
{
offset = GetOffset();
-
- const DWARFAbbreviationDeclaration* abbrev_decl = cu->GetAbbreviations()->GetAbbreviationDeclaration (m_abbr_idx);
- if (abbrev_decl)
+
+ const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
+ if (abbrev_set)
{
- // Make sure the abbreviation code still matches. If it doesn't and
- // the DWARF data was mmap'ed, the backing file might have been modified
- // which is bad news.
- const uint64_t abbrev_code = dwarf2Data->get_debug_info_data().GetULEB128 (&offset);
-
- if (abbrev_decl->Code() == abbrev_code)
- return abbrev_decl;
+ const DWARFAbbreviationDeclaration* abbrev_decl = abbrev_set->GetAbbreviationDeclaration (m_abbr_idx);
+ if (abbrev_decl)
+ {
+ // Make sure the abbreviation code still matches. If it doesn't and
+ // the DWARF data was mmap'ed, the backing file might have been modified
+ // which is bad news.
+ const uint64_t abbrev_code = dwarf2Data->get_debug_info_data().GetULEB128 (&offset);
- dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("0x%8.8x: the DWARF debug information has been modified (abbrev code was %u, and is now %u)",
- GetOffset(),
- (uint32_t)abbrev_decl->Code(),
- (uint32_t)abbrev_code);
+ if (abbrev_decl->Code() == abbrev_code)
+ return abbrev_decl;
+
+ dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("0x%8.8x: the DWARF debug information has been modified (abbrev code was %u, and is now %u)",
+ GetOffset(),
+ (uint32_t)abbrev_decl->Code(),
+ (uint32_t)abbrev_code);
+ }
}
}
offset = DW_INVALID_OFFSET;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index b3a5476227f4..7ba4f52ac297 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -893,13 +893,22 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
// only 1 compile unit which is at offset zero in the DWARF.
// TODO: modify to support LTO .o files where each .o file might
// have multiple DW_TAG_compile_unit tags.
- return info->GetCompileUnit(0).get();
+
+ DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(0).get();
+ if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
+ dwarf_cu->SetUserData(comp_unit);
+ return dwarf_cu;
}
else
{
// Just a normal DWARF file whose user ID for the compile unit is
// the DWARF offset itself
- return info->GetCompileUnit((dw_offset_t)comp_unit->GetID()).get();
+
+ DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID()).get();
+ if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
+ dwarf_cu->SetUserData(comp_unit);
+ return dwarf_cu;
+
}
}
return NULL;
@@ -1037,23 +1046,6 @@ SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
return cu_sp;
}
-static void
-AddRangesToBlock (Block& block,
- DWARFDebugRanges::RangeList& ranges,
- addr_t block_base_addr)
-{
- const size_t num_ranges = ranges.GetSize();
- for (size_t i = 0; i<num_ranges; ++i)
- {
- const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i);
- const addr_t range_base = range.GetRangeBase();
- assert (range_base >= block_base_addr);
- block.AddRange(Block::Range (range_base - block_base_addr, range.GetByteSize()));;
- }
- block.FinalizeRanges ();
-}
-
-
Function *
SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
{
@@ -1397,8 +1389,24 @@ SymbolFileDWARF::ParseFunctionBlocks
subprogram_low_pc = ranges.GetMinRangeBase(0);
}
}
-
- AddRangesToBlock (*block, ranges, subprogram_low_pc);
+
+ const size_t num_ranges = ranges.GetSize();
+ for (size_t i = 0; i<num_ranges; ++i)
+ {
+ const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i);
+ const addr_t range_base = range.GetRangeBase();
+ if (range_base >= subprogram_low_pc)
+ block->AddRange(Block::Range (range_base - subprogram_low_pc, range.GetByteSize()));
+ else
+ {
+ GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64 ") which has a base that is less than the function's low PC 0x%" PRIx64 ". Please file a bug and attach the file at the start of this error message",
+ block->GetID(),
+ range_base,
+ range.GetRangeEnd(),
+ subprogram_low_pc);
+ }
+ }
+ block->FinalizeRanges ();
if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
{
@@ -2786,6 +2794,59 @@ SymbolFileDWARF::GetFunction (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEn
return false;
}
+
+
+SymbolFileDWARF::GlobalVariableMap &
+SymbolFileDWARF::GetGlobalAranges()
+{
+ if (!m_global_aranges_ap)
+ {
+ m_global_aranges_ap.reset (new GlobalVariableMap());
+
+ ModuleSP module_sp = GetObjectFile()->GetModule();
+ if (module_sp)
+ {
+ const size_t num_cus = module_sp->GetNumCompileUnits();
+ for (size_t i = 0; i < num_cus; ++i)
+ {
+ CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
+ if (cu_sp)
+ {
+ VariableListSP globals_sp = cu_sp->GetVariableList(true);
+ if (globals_sp)
+ {
+ const size_t num_globals = globals_sp->GetSize();
+ for (size_t g = 0; g < num_globals; ++g)
+ {
+ VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
+ if (var_sp && !var_sp->GetLocationIsConstantValueData())
+ {
+ const DWARFExpression &location = var_sp->LocationExpression();
+ Value location_result;
+ Error error;
+ if (location.Evaluate(NULL, NULL, NULL, LLDB_INVALID_ADDRESS, NULL, location_result, &error))
+ {
+ if (location_result.GetValueType() == Value::eValueTypeFileAddress)
+ {
+ lldb::addr_t file_addr = location_result.GetScalar().ULongLong();
+ lldb::addr_t byte_size = 1;
+ if (var_sp->GetType())
+ byte_size = var_sp->GetType()->GetByteSize();
+ m_global_aranges_ap->Append(GlobalVariableMap::Entry(file_addr, byte_size, var_sp.get()));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ m_global_aranges_ap->Sort();
+ }
+ return *m_global_aranges_ap;
+}
+
+
uint32_t
SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
{
@@ -2794,10 +2855,11 @@ SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_
static_cast<void*>(so_addr.GetSection().get()),
so_addr.GetOffset(), resolve_scope);
uint32_t resolved = 0;
- if (resolve_scope & ( eSymbolContextCompUnit |
- eSymbolContextFunction |
- eSymbolContextBlock |
- eSymbolContextLineEntry))
+ if (resolve_scope & ( eSymbolContextCompUnit |
+ eSymbolContextFunction |
+ eSymbolContextBlock |
+ eSymbolContextLineEntry |
+ eSymbolContextVariable ))
{
lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
@@ -2805,7 +2867,30 @@ SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_
if (debug_info)
{
const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
- if (cu_offset != DW_INVALID_OFFSET)
+ if (cu_offset == DW_INVALID_OFFSET)
+ {
+ // Global variables are not in the compile unit address ranges. The only way to
+ // currently find global variables is to iterate over the .debug_pubnames or the
+ // __apple_names table and find all items in there that point to DW_TAG_variable
+ // DIEs and then find the address that matches.
+ if (resolve_scope & eSymbolContextVariable)
+ {
+ GlobalVariableMap &map = GetGlobalAranges();
+ const GlobalVariableMap::Entry *entry = map.FindEntryThatContains(file_vm_addr);
+ if (entry && entry->data)
+ {
+ Variable *variable = entry->data;
+ SymbolContextScope *scc = variable->GetSymbolContextScope();
+ if (scc)
+ {
+ scc->CalculateSymbolContext(&sc);
+ sc.variable = variable;
+ }
+ return sc.GetResolvedMask();
+ }
+ }
+ }
+ else
{
uint32_t cu_idx = DW_INVALID_INDEX;
DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
@@ -3409,9 +3494,11 @@ SymbolFileDWARF::ResolveFunction (DWARFCompileUnit *cu,
// Parse all blocks if needed
if (inlined_die)
{
- sc.block = sc.function->GetBlock (true).FindBlockByID (MakeUserID(inlined_die->GetOffset()));
- assert (sc.block != NULL);
- if (sc.block->GetStartAddress (addr) == false)
+ Block &function_block = sc.function->GetBlock (true);
+ sc.block = function_block.FindBlockByID (MakeUserID(inlined_die->GetOffset()));
+ if (sc.block == NULL)
+ sc.block = function_block.FindBlockByID (inlined_die->GetOffset());
+ if (sc.block == NULL || sc.block->GetStartAddress (addr) == false)
addr.Clear();
}
else
@@ -6906,7 +6993,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
clang_type = pointee_clang_type.CreateMemberPointerType(class_clang_type);
- byte_size = clang_type.GetByteSize();
+ byte_size = clang_type.GetByteSize(nullptr);
type_sp.reset( new Type (MakeUserID(die->GetOffset()),
this,
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 230e1a5d3984..d8efdbcb38a4 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -29,6 +29,7 @@
#include "lldb/Core/ConstString.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Core/Flags.h"
+#include "lldb/Core/RangeMap.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/SymbolFile.h"
@@ -557,6 +558,11 @@ protected:
uint32_t type_mask,
TypeSet &type_set);
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb_private::Variable *> GlobalVariableMap;
+
+ GlobalVariableMap &
+ GetGlobalAranges();
+
lldb::ModuleWP m_debug_map_module_wp;
SymbolFileDWARFDebugMap * m_debug_map_symfile;
clang::TranslationUnitDecl * m_clang_tu_decl;
@@ -584,6 +590,7 @@ protected:
std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_ap;
std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap;
std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_ap;
+ std::unique_ptr<GlobalVariableMap> m_global_aranges_ap;
NameToDIE m_function_basename_index; // All concrete functions
NameToDIE m_function_fullname_index; // All concrete functions
NameToDIE m_function_method_index; // All inlined functions
diff --git a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
index 7e484bd8dc73..0eb0f83d5f35 100644
--- a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
+++ b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
@@ -15,6 +15,7 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Error.h"
+#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamString.h"
@@ -146,8 +147,9 @@ UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange&
if (log && log->GetVerbose ())
{
StreamString strm;
- const char *disassemble_format = "${frame.pc}: ";
- inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, NULL, NULL, NULL, disassemble_format);
+ lldb_private::FormatEntity::Entry format;
+ FormatEntity::Parse("${frame.pc}: ", format);
+ inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, NULL, NULL, NULL, &format);
log->PutCString (strm.GetData());
}
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp
index d851ae792181..da25eb84f19e 100644
--- a/source/Symbol/ClangASTContext.cpp
+++ b/source/Symbol/ClangASTContext.cpp
@@ -11,7 +11,7 @@
// C Includes
// C++ Includes
-#include <mutex>
+#include <mutex> // std::once
#include <string>
// Other libraries and framework includes
@@ -708,7 +708,7 @@ uint32_t
ClangASTContext::GetPointerByteSize ()
{
if (m_pointer_byte_size == 0)
- m_pointer_byte_size = GetBasicType(lldb::eBasicTypeVoid).GetPointerType().GetByteSize();
+ m_pointer_byte_size = GetBasicType(lldb::eBasicTypeVoid).GetPointerType().GetByteSize(nullptr);
return m_pointer_byte_size;
}
diff --git a/source/Symbol/ClangASTType.cpp b/source/Symbol/ClangASTType.cpp
index 8b672fac4312..eaff90ab8a0a 100644
--- a/source/Symbol/ClangASTType.cpp
+++ b/source/Symbol/ClangASTType.cpp
@@ -290,6 +290,37 @@ ClangASTType::IsArrayType (ClangASTType *element_type_ptr,
}
bool
+ClangASTType::IsVectorType (ClangASTType *element_type,
+ uint64_t *size) const
+{
+ if (IsValid())
+ {
+ clang::QualType qual_type (GetCanonicalQualType());
+
+ const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+ switch (type_class)
+ {
+ case clang::Type::Vector:
+ {
+ const clang::VectorType *vector_type = qual_type->getAs<clang::VectorType>();
+ if (vector_type)
+ {
+ if (size)
+ *size = vector_type->getNumElements();
+ if (element_type)
+ *element_type = ClangASTType(m_ast, vector_type->getElementType().getAsOpaquePtr());
+ }
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
+bool
ClangASTType::IsRuntimeGeneratedType () const
{
if (!IsValid())
@@ -1663,7 +1694,7 @@ ClangASTType::GetArrayElementType (uint64_t *stride) const
// TODO: the real stride will be >= this value.. find the real one!
if (stride)
- *stride = element_type.GetByteSize();
+ *stride = element_type.GetByteSize(nullptr);
return element_type;
@@ -2062,28 +2093,59 @@ ClangASTType::GetBasicTypeFromAST (lldb::BasicType basic_type) const
//----------------------------------------------------------------------
uint64_t
-ClangASTType::GetBitSize () const
+ClangASTType::GetBitSize (ExecutionContext *exe_ctx) const
{
if (GetCompleteType ())
{
clang::QualType qual_type(GetCanonicalQualType());
- const uint32_t bit_size = m_ast->getTypeSize (qual_type);
- if (bit_size == 0)
+ switch (qual_type->getTypeClass())
{
- if (qual_type->isIncompleteArrayType())
- return m_ast->getTypeSize (qual_type->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified());
+ case clang::Type::ObjCInterface:
+ case clang::Type::ObjCObject:
+ if (exe_ctx && exe_ctx->GetProcessPtr())
+ {
+ ObjCLanguageRuntime *objc_runtime = exe_ctx->GetProcessPtr()->GetObjCLanguageRuntime();
+ if (objc_runtime)
+ {
+ uint64_t bit_size = 0;
+ if (objc_runtime->GetTypeBitSize(*this, bit_size))
+ return bit_size;
+ }
+ }
+ else
+ {
+ static bool g_printed = false;
+ if (!g_printed)
+ {
+ StreamString s;
+ s.Printf("warning: trying to determine the size of type ");
+ DumpTypeDescription(&s);
+ s.Printf("\n without a valid ExecutionContext. this is not reliable. please file a bug against LLDB.\nbacktrace:\n");
+ Host::Backtrace(s, 10);
+ printf("%s\n", s.GetData());
+ g_printed = true;
+ }
+ }
+ // fallthrough
+ default:
+ const uint32_t bit_size = m_ast->getTypeSize (qual_type);
+ if (bit_size == 0)
+ {
+ if (qual_type->isIncompleteArrayType())
+ return m_ast->getTypeSize (qual_type->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified());
+ }
+ if (qual_type->isObjCObjectOrInterfaceType())
+ return bit_size + m_ast->getTypeSize(m_ast->ObjCBuiltinClassTy);
+ return bit_size;
}
- if (qual_type->isObjCObjectOrInterfaceType())
- return bit_size + m_ast->getTypeSize(m_ast->ObjCBuiltinClassTy);
- return bit_size;
}
return 0;
}
uint64_t
-ClangASTType::GetByteSize () const
+ClangASTType::GetByteSize (ExecutionContext *exe_ctx) const
{
- return (GetBitSize () + 7) / 8;
+ return (GetBitSize (exe_ctx) + 7) / 8;
}
size_t
@@ -3416,7 +3478,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx,
child_byte_offset = bit_offset/8;
ClangASTType base_class_clang_type(m_ast, base_class->getType());
child_name = base_class_clang_type.GetTypeName().AsCString("");
- uint64_t base_class_clang_type_bit_size = base_class_clang_type.GetBitSize();
+ uint64_t base_class_clang_type_bit_size = base_class_clang_type.GetBitSize(nullptr);
// Base classes bit sizes should be a multiple of 8 bits in size
assert (base_class_clang_type_bit_size % 8 == 0);
@@ -3444,7 +3506,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx,
// alignment (field_type_info.second) from the AST context.
ClangASTType field_clang_type (m_ast, field->getType());
assert(field_idx < record_layout.getFieldCount());
- child_byte_size = field_clang_type.GetByteSize();
+ child_byte_size = field_clang_type.GetByteSize(exe_ctx);
// Figure out the field offset within the current struct/union/class type
bit_offset = record_layout.getFieldOffset (field_idx);
@@ -3609,7 +3671,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx,
// We have a pointer to an simple type
if (idx == 0 && pointee_clang_type.GetCompleteType())
{
- child_byte_size = pointee_clang_type.GetByteSize();
+ child_byte_size = pointee_clang_type.GetByteSize(exe_ctx);
child_byte_offset = 0;
return pointee_clang_type;
}
@@ -3630,7 +3692,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx,
char element_name[64];
::snprintf (element_name, sizeof (element_name), "[%zu]", idx);
child_name.assign(element_name);
- child_byte_size = element_type.GetByteSize();
+ child_byte_size = element_type.GetByteSize(exe_ctx);
child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
return element_type;
}
@@ -3651,7 +3713,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx,
char element_name[64];
::snprintf (element_name, sizeof (element_name), "[%zu]", idx);
child_name.assign(element_name);
- child_byte_size = element_type.GetByteSize();
+ child_byte_size = element_type.GetByteSize(exe_ctx);
child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
return element_type;
}
@@ -3701,7 +3763,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx,
// We have a pointer to an simple type
if (idx == 0)
{
- child_byte_size = pointee_clang_type.GetByteSize();
+ child_byte_size = pointee_clang_type.GetByteSize(exe_ctx);
child_byte_offset = 0;
return pointee_clang_type;
}
@@ -3745,7 +3807,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx,
// We have a pointer to an simple type
if (idx == 0)
{
- child_byte_size = pointee_clang_type.GetByteSize();
+ child_byte_size = pointee_clang_type.GetByteSize(exe_ctx);
child_byte_offset = 0;
return pointee_clang_type;
}
@@ -6643,7 +6705,7 @@ ClangASTType::GetValueAsScalar (const lldb_private::DataExtractor &data,
if (encoding == lldb::eEncodingInvalid || count != 1)
return false;
- const uint64_t byte_size = GetByteSize();
+ const uint64_t byte_size = GetByteSize(nullptr);
lldb::offset_t offset = data_byte_offset;
switch (encoding)
{
@@ -6771,7 +6833,7 @@ ClangASTType::SetValueFromScalar (const Scalar &value, Stream &strm)
if (encoding == lldb::eEncodingInvalid || count != 1)
return false;
- const uint64_t bit_width = GetBitSize();
+ const uint64_t bit_width = GetBitSize(nullptr);
// This function doesn't currently handle non-byte aligned assignments
if ((bit_width % 8) != 0)
return false;
@@ -6851,7 +6913,7 @@ ClangASTType::ReadFromMemory (lldb_private::ExecutionContext *exe_ctx,
if (!GetCompleteType())
return false;
- const uint64_t byte_size = GetByteSize();
+ const uint64_t byte_size = GetByteSize(exe_ctx);
if (data.GetByteSize() < byte_size)
{
lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0'));
@@ -6901,7 +6963,7 @@ ClangASTType::WriteToMemory (lldb_private::ExecutionContext *exe_ctx,
if (!GetCompleteType())
return false;
- const uint64_t byte_size = GetByteSize();
+ const uint64_t byte_size = GetByteSize(exe_ctx);
if (byte_size > 0)
{
diff --git a/source/Symbol/CompactUnwindInfo.cpp b/source/Symbol/CompactUnwindInfo.cpp
index 8c6a2e7214c3..e7153446cd16 100644
--- a/source/Symbol/CompactUnwindInfo.cpp
+++ b/source/Symbol/CompactUnwindInfo.cpp
@@ -809,8 +809,16 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi
}
}
+ if (mode == UNWIND_X86_64_MODE_STACK_IND)
+ {
+ row->SetCFAOffset (stack_size);
+ }
+ else
+ {
+ row->SetCFAOffset (stack_size * wordsize);
+ }
+
row->SetCFARegister (x86_64_eh_regnum::rsp);
- row->SetCFAOffset (stack_size * wordsize);
row->SetOffset (0);
row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rip, wordsize * -1, true);
row->SetRegisterLocationToIsCFAPlusOffset (x86_64_eh_regnum::rsp, 0, true);
@@ -919,10 +927,10 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi
case UNWIND_X86_64_REG_R14:
case UNWIND_X86_64_REG_R15:
case UNWIND_X86_64_REG_RBP:
- row->SetRegisterLocationToAtCFAPlusOffset (translate_to_eh_frame_regnum_x86_64 (registers[i]), wordsize * -saved_registers_offset, true);
+ row->SetRegisterLocationToAtCFAPlusOffset (translate_to_eh_frame_regnum_x86_64 (registers[i]), wordsize * -saved_registers_offset, true);
+ saved_registers_offset++;
break;
}
- saved_registers_offset++;
}
}
unwind_plan.AppendRow (row);
@@ -1084,7 +1092,16 @@ CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function
}
row->SetCFARegister (i386_eh_regnum::esp);
- row->SetCFAOffset (stack_size * wordsize);
+
+ if (mode == UNWIND_X86_MODE_STACK_IND)
+ {
+ row->SetCFAOffset (stack_size);
+ }
+ else
+ {
+ row->SetCFAOffset (stack_size * wordsize);
+ }
+
row->SetOffset (0);
row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::eip, wordsize * -1, true);
row->SetRegisterLocationToIsCFAPlusOffset (i386_eh_regnum::esp, 0, true);
@@ -1193,10 +1210,10 @@ CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function
case UNWIND_X86_REG_EDI:
case UNWIND_X86_REG_ESI:
case UNWIND_X86_REG_EBP:
- row->SetRegisterLocationToAtCFAPlusOffset (translate_to_eh_frame_regnum_i386 (registers[i]), wordsize * -saved_registers_offset, true);
+ row->SetRegisterLocationToAtCFAPlusOffset (translate_to_eh_frame_regnum_i386 (registers[i]), wordsize * -saved_registers_offset, true);
+ saved_registers_offset++;
break;
}
- saved_registers_offset++;
}
}
diff --git a/source/Symbol/SymbolContext.cpp b/source/Symbol/SymbolContext.cpp
index 129f4def0067..62ae6ac464ce 100644
--- a/source/Symbol/SymbolContext.cpp
+++ b/source/Symbol/SymbolContext.cpp
@@ -13,7 +13,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/Host.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Host/StringConvert.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
@@ -21,6 +21,7 @@
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/Variable.h"
#include "lldb/Target/Target.h"
using namespace lldb;
@@ -33,7 +34,8 @@ SymbolContext::SymbolContext() :
function (nullptr),
block (nullptr),
line_entry (),
- symbol (nullptr)
+ symbol (nullptr),
+ variable (nullptr)
{
}
@@ -44,7 +46,8 @@ SymbolContext::SymbolContext(const ModuleSP& m, CompileUnit *cu, Function *f, Bl
function (f),
block (b),
line_entry (),
- symbol (s)
+ symbol (s),
+ variable (nullptr)
{
if (le)
line_entry = *le;
@@ -57,7 +60,8 @@ SymbolContext::SymbolContext(const TargetSP &t, const ModuleSP& m, CompileUnit *
function (f),
block (b),
line_entry (),
- symbol (s)
+ symbol (s),
+ variable (nullptr)
{
if (le)
line_entry = *le;
@@ -70,7 +74,8 @@ SymbolContext::SymbolContext(const SymbolContext& rhs) :
function (rhs.function),
block (rhs.block),
line_entry (rhs.line_entry),
- symbol (rhs.symbol)
+ symbol (rhs.symbol),
+ variable (rhs.variable)
{
}
@@ -82,7 +87,8 @@ SymbolContext::SymbolContext (SymbolContextScope *sc_scope) :
function (nullptr),
block (nullptr),
line_entry (),
- symbol (nullptr)
+ symbol (nullptr),
+ variable (nullptr)
{
sc_scope->CalculateSymbolContext (this);
}
@@ -103,6 +109,7 @@ SymbolContext::operator= (const SymbolContext& rhs)
block = rhs.block;
line_entry = rhs.line_entry;
symbol = rhs.symbol;
+ variable = rhs.variable;
}
return *this;
}
@@ -118,6 +125,7 @@ SymbolContext::Clear(bool clear_target)
block = nullptr;
line_entry.Clear();
symbol = nullptr;
+ variable = nullptr;
}
bool
@@ -309,6 +317,37 @@ SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *t
symbol->GetDescription(s, level, target);
s->EOL();
}
+
+ if (variable != nullptr)
+ {
+ s->Indent(" Variable: ");
+
+ s->Printf("id = {0x%8.8" PRIx64 "}, ", variable->GetID());
+
+ switch (variable->GetScope())
+ {
+ case eValueTypeVariableGlobal:
+ s->PutCString("kind = global, ");
+ break;
+
+ case eValueTypeVariableStatic:
+ s->PutCString("kind = static, ");
+ break;
+
+ case eValueTypeVariableArgument:
+ s->PutCString("kind = argument, ");
+ break;
+
+ case eValueTypeVariableLocal:
+ s->PutCString("kind = local, ");
+ break;
+
+ default:
+ break;
+ }
+
+ s->Printf ("name = \"%s\"\n", variable->GetName().GetCString());
+ }
}
uint32_t
@@ -322,6 +361,7 @@ SymbolContext::GetResolvedMask () const
if (block) resolved_mask |= eSymbolContextBlock;
if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry;
if (symbol) resolved_mask |= eSymbolContextSymbol;
+ if (variable) resolved_mask |= eSymbolContextVariable;
return resolved_mask;
}
@@ -377,6 +417,12 @@ SymbolContext::Dump(Stream *s, Target *target) const
if (symbol != nullptr && symbol->GetMangled())
*s << ' ' << symbol->GetMangled().GetName().AsCString();
s->EOL();
+ *s << "Variable = " << (void *)variable;
+ if (variable != nullptr)
+ {
+ *s << " {0x" << variable->GetID() << "} " << variable->GetType()->GetName();
+ s->EOL();
+ }
s->IndentLess();
s->IndentLess();
}
@@ -389,7 +435,8 @@ lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
&& lhs.module_sp.get() == rhs.module_sp.get()
&& lhs.comp_unit == rhs.comp_unit
&& lhs.target_sp.get() == rhs.target_sp.get()
- && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0;
+ && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0
+ && lhs.variable == rhs.variable;
}
bool
@@ -400,7 +447,8 @@ lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
|| lhs.module_sp.get() != rhs.module_sp.get()
|| lhs.comp_unit != rhs.comp_unit
|| lhs.target_sp.get() != rhs.target_sp.get()
- || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0;
+ || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0
+ || lhs.variable != rhs.variable;
}
bool
@@ -730,12 +778,12 @@ SymbolContextSpecifier::AddSpecification (const char *spec_string, Specification
m_type |= eFileSpecified;
break;
case eLineStartSpecified:
- m_start_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
+ m_start_line = StringConvert::ToSInt32(spec_string, 0, 0, &return_value);
if (return_value)
m_type |= eLineStartSpecified;
break;
case eLineEndSpecified:
- m_end_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
+ m_end_line = StringConvert::ToSInt32(spec_string, 0, 0, &return_value);
if (return_value)
m_type |= eLineEndSpecified;
break;
diff --git a/source/Symbol/Type.cpp b/source/Symbol/Type.cpp
index 42b76590aaea..6e67f4695d9f 100644
--- a/source/Symbol/Type.cpp
+++ b/source/Symbol/Type.cpp
@@ -336,7 +336,7 @@ Type::GetByteSize()
if (encoding_type)
m_byte_size = encoding_type->GetByteSize();
if (m_byte_size == 0)
- m_byte_size = GetClangLayoutType().GetByteSize();
+ m_byte_size = GetClangLayoutType().GetByteSize(nullptr);
}
break;
@@ -1141,7 +1141,7 @@ TypeImpl::GetPointerType () const
{
if (m_dynamic_type.IsValid())
{
- return TypeImpl(m_static_type, m_dynamic_type.GetPointerType());
+ return TypeImpl(m_static_type.GetPointerType(), m_dynamic_type.GetPointerType());
}
return TypeImpl(m_static_type.GetPointerType());
}
@@ -1156,7 +1156,7 @@ TypeImpl::GetPointeeType () const
{
if (m_dynamic_type.IsValid())
{
- return TypeImpl(m_static_type, m_dynamic_type.GetPointeeType());
+ return TypeImpl(m_static_type.GetPointeeType(), m_dynamic_type.GetPointeeType());
}
return TypeImpl(m_static_type.GetPointeeType());
}
@@ -1171,7 +1171,7 @@ TypeImpl::GetReferenceType () const
{
if (m_dynamic_type.IsValid())
{
- return TypeImpl(m_static_type, m_dynamic_type.GetLValueReferenceType());
+ return TypeImpl(m_static_type.GetReferenceType(), m_dynamic_type.GetLValueReferenceType());
}
return TypeImpl(m_static_type.GetReferenceType());
}
@@ -1186,7 +1186,7 @@ TypeImpl::GetTypedefedType () const
{
if (m_dynamic_type.IsValid())
{
- return TypeImpl(m_static_type, m_dynamic_type.GetTypedefedType());
+ return TypeImpl(m_static_type.GetTypedefedType(), m_dynamic_type.GetTypedefedType());
}
return TypeImpl(m_static_type.GetTypedefedType());
}
@@ -1201,7 +1201,7 @@ TypeImpl::GetDereferencedType () const
{
if (m_dynamic_type.IsValid())
{
- return TypeImpl(m_static_type, m_dynamic_type.GetNonReferenceType());
+ return TypeImpl(m_static_type.GetDereferencedType(), m_dynamic_type.GetNonReferenceType());
}
return TypeImpl(m_static_type.GetDereferencedType());
}
@@ -1216,7 +1216,7 @@ TypeImpl::GetUnqualifiedType() const
{
if (m_dynamic_type.IsValid())
{
- return TypeImpl(m_static_type, m_dynamic_type.GetFullyUnqualifiedType());
+ return TypeImpl(m_static_type.GetUnqualifiedType(), m_dynamic_type.GetFullyUnqualifiedType());
}
return TypeImpl(m_static_type.GetUnqualifiedType());
}
@@ -1231,7 +1231,7 @@ TypeImpl::GetCanonicalType() const
{
if (m_dynamic_type.IsValid())
{
- return TypeImpl(m_static_type, m_dynamic_type.GetCanonicalType());
+ return TypeImpl(m_static_type.GetCanonicalType(), m_dynamic_type.GetCanonicalType());
}
return TypeImpl(m_static_type.GetCanonicalType());
}
diff --git a/source/Symbol/Variable.cpp b/source/Symbol/Variable.cpp
index b1a60f6b4a24..4c03a307296d 100644
--- a/source/Symbol/Variable.cpp
+++ b/source/Symbol/Variable.cpp
@@ -203,7 +203,10 @@ void
Variable::CalculateSymbolContext (SymbolContext *sc)
{
if (m_owner_scope)
+ {
m_owner_scope->CalculateSymbolContext(sc);
+ sc->variable = this;
+ }
else
sc->Clear(false);
}
diff --git a/source/Target/ExecutionContext.cpp b/source/Target/ExecutionContext.cpp
index db4025f40c05..e03a560bd063 100644
--- a/source/Target/ExecutionContext.cpp
+++ b/source/Target/ExecutionContext.cpp
@@ -705,7 +705,11 @@ ExecutionContextRef::SetTargetPtr (Target* target, bool adopt_selected)
if (process_sp)
{
// Only fill in the thread and frame if our process is stopped
- if (StateIsStoppedState (process_sp->GetState(), true))
+ // Don't just check the state, since we might be in the middle of
+ // resuming.
+ Process::StopLocker stop_locker;
+
+ if (stop_locker.TryLock(&process_sp->GetRunLock()) && StateIsStoppedState (process_sp->GetState(), true))
{
lldb::ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
if (!thread_sp)
diff --git a/source/Target/LanguageRuntime.cpp b/source/Target/LanguageRuntime.cpp
index 358bffee3a4d..123ee93d322f 100644
--- a/source/Target/LanguageRuntime.cpp
+++ b/source/Target/LanguageRuntime.cpp
@@ -337,6 +337,9 @@ struct language_name_pair language_names[] =
{ "swift", eLanguageTypeSwift },
{ "julia", eLanguageTypeJulia },
{ "dylan", eLanguageTypeDylan },
+ { "c++14", eLanguageTypeC_plus_plus_14 },
+ { "fortran03", eLanguageTypeFortran03 },
+ { "fortran08", eLanguageTypeFortran08 },
// Now synonyms, in arbitrary order
{ "objc", eLanguageTypeObjC },
{ "objc++", eLanguageTypeObjC_plus_plus }
diff --git a/source/Target/ObjCLanguageRuntime.cpp b/source/Target/ObjCLanguageRuntime.cpp
index b182407bf68e..3d7a9021343a 100644
--- a/source/Target/ObjCLanguageRuntime.cpp
+++ b/source/Target/ObjCLanguageRuntime.cpp
@@ -34,9 +34,14 @@ ObjCLanguageRuntime::~ObjCLanguageRuntime()
ObjCLanguageRuntime::ObjCLanguageRuntime (Process *process) :
LanguageRuntime (process),
+ m_impl_cache(),
m_has_new_literals_and_indexing (eLazyBoolCalculate),
m_isa_to_descriptor(),
- m_isa_to_descriptor_stop_id (UINT32_MAX)
+ m_hash_to_isa_map(),
+ m_type_size_cache(),
+ m_isa_to_descriptor_stop_id (UINT32_MAX),
+ m_complete_class_cache(),
+ m_negative_complete_class_cache()
{
}
@@ -626,3 +631,42 @@ ObjCLanguageRuntime::GetEncodingToType ()
{
return nullptr;
}
+
+bool
+ObjCLanguageRuntime::GetTypeBitSize (const ClangASTType& clang_type,
+ uint64_t &size)
+{
+ void *opaque_ptr = clang_type.GetQualType().getAsOpaquePtr();
+ size = m_type_size_cache.Lookup(opaque_ptr);
+ // an ObjC object will at least have an ISA, so 0 is definitely not OK
+ if (size > 0)
+ return true;
+
+ ClassDescriptorSP class_descriptor_sp = GetClassDescriptorFromClassName(clang_type.GetTypeName());
+ if (!class_descriptor_sp)
+ return false;
+
+ int32_t max_offset = INT32_MIN;
+ uint64_t sizeof_max = 0;
+ bool found = false;
+
+ for (size_t idx = 0;
+ idx < class_descriptor_sp->GetNumIVars();
+ idx++)
+ {
+ const auto& ivar = class_descriptor_sp->GetIVarAtIndex(idx);
+ int32_t cur_offset = ivar.m_offset;
+ if (cur_offset > max_offset)
+ {
+ max_offset = cur_offset;
+ sizeof_max = ivar.m_size;
+ found = true;
+ }
+ }
+
+ size = 8 * (max_offset + sizeof_max);
+ if (found)
+ m_type_size_cache.Insert(opaque_ptr, size);
+
+ return found;
+}
diff --git a/source/Target/Platform.cpp b/source/Target/Platform.cpp
index 4ebd18b8bfd0..09c9efc14b08 100644
--- a/source/Target/Platform.cpp
+++ b/source/Target/Platform.cpp
@@ -286,8 +286,7 @@ Platform::Platform (bool is_host) :
m_minor_os_version (UINT32_MAX),
m_update_os_version (UINT32_MAX),
m_system_arch(),
- m_uid_map_mutex (Mutex::eMutexTypeNormal),
- m_gid_map_mutex (Mutex::eMutexTypeNormal),
+ m_mutex (Mutex::eMutexTypeRecursive),
m_uid_map(),
m_gid_map(),
m_max_uid_name_len (0),
@@ -299,8 +298,7 @@ Platform::Platform (bool is_host) :
m_ssh_opts (),
m_ignores_remote_hostname (false),
m_trap_handlers(),
- m_calculated_trap_handlers (false),
- m_trap_handler_mutex()
+ m_calculated_trap_handlers (false)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
@@ -384,6 +382,8 @@ Platform::GetOSVersion (uint32_t &major,
uint32_t &minor,
uint32_t &update)
{
+ Mutex::Locker locker (m_mutex);
+
bool success = m_major_os_version != UINT32_MAX;
if (IsHost())
{
@@ -463,7 +463,7 @@ Platform::GetOSKernelDescription (std::string &s)
}
void
-Platform::AddClangModuleCompilationOptions (std::vector<std::string> &options)
+Platform::AddClangModuleCompilationOptions (Target *target, std::vector<std::string> &options)
{
std::vector<std::string> default_compilation_options =
{
@@ -1103,6 +1103,20 @@ Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
return error;
}
+Error
+Platform::KillProcess (const lldb::pid_t pid)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf ("Platform::%s, pid %" PRIu64, __FUNCTION__, pid);
+
+ if (!IsHost ())
+ return Error ("base lldb_private::Platform class can't launch remote processes");
+
+ Host::Kill (pid, SIGTERM);
+ return Error();
+}
+
lldb::ProcessSP
Platform::DebugProcess (ProcessLaunchInfo &launch_info,
Debugger &debugger,
@@ -1233,7 +1247,64 @@ Platform::PutFile (const FileSpec& source,
uint32_t uid,
uint32_t gid)
{
- Error error("unimplemented");
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
+ if (log)
+ log->Printf("[PutFile] Using block by block transfer....\n");
+
+ uint32_t source_open_options = File::eOpenOptionRead;
+ if (source.GetFileType() == FileSpec::eFileTypeSymbolicLink)
+ source_open_options |= File::eOpenoptionDontFollowSymlinks;
+
+ File source_file(source, source_open_options, lldb::eFilePermissionsUserRW);
+ Error error;
+ uint32_t permissions = source_file.GetPermissions(error);
+ if (permissions == 0)
+ permissions = lldb::eFilePermissionsFileDefault;
+
+ if (!source_file.IsValid())
+ return Error("PutFile: unable to open source file");
+ lldb::user_id_t dest_file = OpenFile (destination,
+ File::eOpenOptionCanCreate |
+ File::eOpenOptionWrite |
+ File::eOpenOptionTruncate,
+ permissions,
+ error);
+ if (log)
+ log->Printf ("dest_file = %" PRIu64 "\n", dest_file);
+
+ if (error.Fail())
+ return error;
+ if (dest_file == UINT64_MAX)
+ return Error("unable to open target file");
+ lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0));
+ uint64_t offset = 0;
+ for (;;)
+ {
+ size_t bytes_read = buffer_sp->GetByteSize();
+ error = source_file.Read(buffer_sp->GetBytes(), bytes_read);
+ if (error.Fail() || bytes_read == 0)
+ break;
+
+ const uint64_t bytes_written = WriteFile(dest_file, offset,
+ buffer_sp->GetBytes(), bytes_read, error);
+ if (error.Fail())
+ break;
+
+ offset += bytes_written;
+ if (bytes_written != bytes_read)
+ {
+ // We didn't write the correct number of bytes, so adjust
+ // the file position in the source file we are reading from...
+ source_file.SeekFromStart(offset);
+ }
+ }
+ CloseFile(dest_file, error);
+
+ if (uid == UINT32_MAX && gid == UINT32_MAX)
+ return error;
+
+ // TODO: ChownFile?
+
return error;
}
@@ -1528,7 +1599,7 @@ Platform::GetTrapHandlerSymbolNames ()
{
if (!m_calculated_trap_handlers)
{
- Mutex::Locker locker (m_trap_handler_mutex);
+ Mutex::Locker locker (m_mutex);
if (!m_calculated_trap_handlers)
{
CalculateTrapHandlerSymbolNames();
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index 106678da2684..f7a26f676aba 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -720,6 +720,7 @@ Process::Process(Target &target, Listener &listener, const UnixSignalsSP &unix_s
m_process_input_reader (),
m_stdio_communication ("process.stdio"),
m_stdio_communication_mutex (Mutex::eMutexTypeRecursive),
+ m_stdio_disable(true),
m_stdout_data (),
m_stderr_data (),
m_profile_data_comm_mutex (Mutex::eMutexTypeRecursive),
@@ -3121,6 +3122,11 @@ Process::Launch (ProcessLaunchInfo &launch_info)
StartPrivateStateThread ();
m_stop_info_override_callback = GetTarget().GetArchitecture().GetStopInfoOverrideCallback();
+
+ // Target was stopped at entry as was intended. Need to notify the listeners
+ // about it.
+ if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == true)
+ HandlePrivateEvent(event_sp);
}
else if (state == eStateExited)
{
@@ -3643,7 +3649,8 @@ Process::PrivateResume ()
}
else
{
- // Somebody wanted to run without running. So generate a continue & a stopped event,
+ // Somebody wanted to run without running (e.g. we were faking a step from one frame of a set of inlined
+ // frames that share the same PC to another.) So generate a continue & a stopped event,
// and let the world handle them.
if (log)
log->Printf ("Process::PrivateResume() asked to simulate a start & stop.");
@@ -3905,6 +3912,7 @@ Process::Destroy ()
}
m_stdio_communication.StopReadThread();
m_stdio_communication.Disconnect();
+ m_stdio_disable = true;
if (m_process_input_reader)
{
diff --git a/source/Target/ProcessLaunchInfo.cpp b/source/Target/ProcessLaunchInfo.cpp
index 451c42d18bfa..b841b2c066a3 100644
--- a/source/Target/ProcessLaunchInfo.cpp
+++ b/source/Target/ProcessLaunchInfo.cpp
@@ -344,7 +344,14 @@ ProcessLaunchInfo::FinalizeFileActions (Target *target, bool default_to_use_pty)
log->Printf ("ProcessLaunchInfo::%s default_to_use_pty is set, and at least one stdin/stderr/stdout is unset, so generating a pty to use for it",
__FUNCTION__);
- if (m_pty->OpenFirstAvailableMaster(O_RDWR| O_NOCTTY, NULL, 0))
+ int open_flags = O_RDWR | O_NOCTTY;
+#if !defined(_MSC_VER)
+ // We really shouldn't be specifying platform specific flags
+ // that are intended for a system call in generic code. But
+ // this will have to do for now.
+ open_flags |= O_CLOEXEC;
+#endif
+ if (m_pty->OpenFirstAvailableMaster(open_flags, NULL, 0))
{
const char *slave_path = m_pty->GetSlaveName(NULL, 0);
diff --git a/source/Target/StackFrame.cpp b/source/Target/StackFrame.cpp
index c46db4cfadf9..01a8c9ab88f2 100644
--- a/source/Target/StackFrame.cpp
+++ b/source/Target/StackFrame.cpp
@@ -18,6 +18,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
+#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Core/ValueObjectConstResult.h"
@@ -1373,11 +1374,11 @@ StackFrame::DumpUsingSettingsFormat (Stream *strm, const char *frame_marker)
if (frame_marker)
s.PutCString(frame_marker);
- const char *frame_format = NULL;
+ const FormatEntity::Entry *frame_format = NULL;
Target *target = exe_ctx.GetTargetPtr();
if (target)
frame_format = target->GetDebugger().GetFrameFormat();
- if (frame_format && Debugger::FormatPrompt (frame_format, &m_sc, &exe_ctx, NULL, s))
+ if (frame_format && FormatEntity::Format(*frame_format, s, &m_sc, &exe_ctx, NULL, NULL, false, false))
{
strm->Write(s.GetData(), s.GetSize());
}
diff --git a/source/Target/StopInfo.cpp b/source/Target/StopInfo.cpp
index 4b57ca65a2df..457b94c1dc20 100644
--- a/source/Target/StopInfo.cpp
+++ b/source/Target/StopInfo.cpp
@@ -479,7 +479,12 @@ protected:
condition_says_stop);
}
if (!condition_says_stop)
+ {
+ // We don't want to increment the hit count of breakpoints if the condition fails.
+ // We've already bumped it by the time we get here, so undo the bump:
+ bp_loc_sp->UndoBumpHitCount();
continue;
+ }
}
}
diff --git a/source/Target/TargetList.cpp b/source/Target/TargetList.cpp
index 28ad47e3d81d..bbed0fb0bc12 100644
--- a/source/Target/TargetList.cpp
+++ b/source/Target/TargetList.cpp
@@ -98,12 +98,12 @@ TargetList::CreateTarget (Debugger &debugger,
Error
TargetList::CreateTargetInternal (Debugger &debugger,
- const char *user_exe_path,
- const char *triple_cstr,
- bool get_dependent_files,
- const OptionGroupPlatform *platform_options,
- TargetSP &target_sp,
- bool is_dummy_target)
+ const char *user_exe_path,
+ const char *triple_cstr,
+ bool get_dependent_files,
+ const OptionGroupPlatform *platform_options,
+ TargetSP &target_sp,
+ bool is_dummy_target)
{
Error error;
PlatformSP platform_sp;
@@ -126,16 +126,24 @@ TargetList::CreateTargetInternal (Debugger &debugger,
bool prefer_platform_arch = false;
CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
+
+ // let's see if there is already an existing plaform before we go creating another...
+ platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
+
if (platform_options && platform_options->PlatformWasSpecified ())
{
- const bool select_platform = true;
- platform_sp = platform_options->CreatePlatformWithOptions (interpreter,
- arch,
- select_platform,
- error,
- platform_arch);
- if (!platform_sp)
- return error;
+ // 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;
+ }
}
if (user_exe_path && user_exe_path[0])
@@ -361,12 +369,12 @@ TargetList::CreateDummyTarget (Debugger &debugger,
Error
TargetList::CreateTargetInternal (Debugger &debugger,
- const char *user_exe_path,
- const ArchSpec& specified_arch,
- bool get_dependent_files,
- lldb::PlatformSP &platform_sp,
- lldb::TargetSP &target_sp,
- bool is_dummy_target)
+ const char *user_exe_path,
+ const ArchSpec& specified_arch,
+ bool get_dependent_files,
+ lldb::PlatformSP &platform_sp,
+ lldb::TargetSP &target_sp,
+ bool is_dummy_target)
{
Timer scoped_timer (__PRETTY_FUNCTION__,
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index b532d8d71c8f..6fd5cdf0d15c 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -13,6 +13,7 @@
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/State.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
@@ -66,8 +67,8 @@ g_properties[] =
{ "step-in-avoid-nodebug", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, step-in will not stop in functions with no debug information." },
{ "step-out-avoid-nodebug", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, when step-in/step-out/step-over leave the current frame, they will continue to step out till they come to a function with "
"debug information. Passing a frame argument to step-out will override this option." },
- { "step-avoid-regexp", OptionValue::eTypeRegex , true , REG_EXTENDED, "^std::", NULL, "A regular expression defining functions step-in won't stop in." },
- { "step-avoid-libraries", OptionValue::eTypeFileSpecList , true , REG_EXTENDED, NULL, NULL, "A list of libraries that source stepping won't stop in." },
+ { "step-avoid-regexp", OptionValue::eTypeRegex , true , 0, "^std::", NULL, "A regular expression defining functions step-in won't stop in." },
+ { "step-avoid-libraries", OptionValue::eTypeFileSpecList , true , 0, NULL, NULL, "A list of libraries that source stepping won't stop in." },
{ "trace-thread", OptionValue::eTypeBoolean, false, false, NULL, NULL, "If true, this thread will single-step and log execution." },
{ NULL , OptionValue::eTypeInvalid, false, 0 , NULL, NULL, NULL }
};
@@ -2033,7 +2034,7 @@ Thread::DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx)
StackFrameSP frame_sp;
SymbolContext frame_sc;
- if (frame_idx != LLDB_INVALID_INDEX32)
+ if (frame_idx != LLDB_INVALID_FRAME_ID)
{
frame_sp = GetStackFrameAtIndex (frame_idx);
if (frame_sp)
@@ -2043,13 +2044,17 @@ Thread::DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx)
}
}
- const char *thread_format = exe_ctx.GetTargetRef().GetDebugger().GetThreadFormat();
+ const FormatEntity::Entry *thread_format = exe_ctx.GetTargetRef().GetDebugger().GetThreadFormat();
assert (thread_format);
- Debugger::FormatPrompt (thread_format,
- frame_sp ? &frame_sc : NULL,
- &exe_ctx,
- NULL,
- strm);
+
+ FormatEntity::Format(*thread_format,
+ strm,
+ frame_sp ? &frame_sc : NULL,
+ &exe_ctx,
+ NULL,
+ NULL,
+ false,
+ false);
}
void
diff --git a/source/Target/ThreadPlanTracer.cpp b/source/Target/ThreadPlanTracer.cpp
index d2b039d69f67..0629eb9981ef 100644
--- a/source/Target/ThreadPlanTracer.cpp
+++ b/source/Target/ThreadPlanTracer.cpp
@@ -212,7 +212,7 @@ ThreadPlanAssemblyTracer::Log ()
const bool show_bytes = true;
const bool show_address = true;
Instruction *instruction = instruction_list.GetInstructionAtIndex(0).get();
- const char *disassemble_format = "${addr-file-or-load}: ";
+ const FormatEntity::Entry *disassemble_format = m_thread.GetProcess()->GetTarget().GetDebugger().GetDisassemblyFormat();
instruction->Dump (stream,
max_opcode_byte_size,
show_address,
diff --git a/source/Target/UnixSignals.cpp b/source/Target/UnixSignals.cpp
index 16a35b5f5a2f..7f57579c1ee5 100644
--- a/source/Target/UnixSignals.cpp
+++ b/source/Target/UnixSignals.cpp
@@ -13,7 +13,7 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Host/StringConvert.h"
using namespace lldb_private;
@@ -148,7 +148,7 @@ UnixSignals::GetSignalNumberFromName (const char *name) const
return pos->first;
}
- const int32_t signo = Args::StringToSInt32(name, LLDB_INVALID_SIGNAL_NUMBER, 0);
+ const int32_t signo = StringConvert::ToSInt32(name, LLDB_INVALID_SIGNAL_NUMBER, 0);
if (signo != LLDB_INVALID_SIGNAL_NUMBER)
return signo;
return LLDB_INVALID_SIGNAL_NUMBER;
diff --git a/source/Utility/StringExtractorGDBRemote.cpp b/source/Utility/StringExtractorGDBRemote.cpp
index 161ac6a026f2..a137d365984f 100644
--- a/source/Utility/StringExtractorGDBRemote.cpp
+++ b/source/Utility/StringExtractorGDBRemote.cpp
@@ -265,6 +265,9 @@ StringExtractorGDBRemote::GetServerPacketType () const
case 'H':
return eServerPacketType_H;
+ case 'I':
+ return eServerPacketType_I;
+
case 'k':
if (packet_size == 1) return eServerPacketType_k;
break;
diff --git a/source/Utility/StringExtractorGDBRemote.h b/source/Utility/StringExtractorGDBRemote.h
index e16403c2d154..b51be7d7c28a 100644
--- a/source/Utility/StringExtractorGDBRemote.h
+++ b/source/Utility/StringExtractorGDBRemote.h
@@ -130,6 +130,7 @@ public:
eServerPacketType_g,
eServerPacketType_G,
eServerPacketType_H,
+ eServerPacketType_I, // stdin notification
eServerPacketType_k,
eServerPacketType_m,
eServerPacketType_M,
diff --git a/source/Utility/UriParser.cpp b/source/Utility/UriParser.cpp
index bf1e601485b4..1d4402feec6e 100644
--- a/source/Utility/UriParser.cpp
+++ b/source/Utility/UriParser.cpp
@@ -15,6 +15,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/Host/StringConvert.h"
+
+using namespace lldb_private;
//----------------------------------------------------------------------
// UriParser::Parse
@@ -33,17 +36,21 @@ UriParser::Parse(const char* uri,
char path_buf[2049] = {'/', 0};
bool ok = false;
- if (4==sscanf(uri, "%99[^:/]://%255[^/:]:%[^/]/%2047s", scheme_buf, hostname_buf, port_buf, path_buf+1)) { ok = true; }
- else if (3==sscanf(uri, "%99[^:/]://%255[^/:]:%[^/]", scheme_buf, hostname_buf, port_buf)) { ok = true; }
+ if (4==sscanf(uri, "%99[^:/]://%255[^/:]:%10[^/]/%2047s", scheme_buf, hostname_buf, port_buf, path_buf+1)) { ok = true; }
+ else if (3==sscanf(uri, "%99[^:/]://%255[^/:]:%10[^/]", scheme_buf, hostname_buf, port_buf)) { ok = true; }
else if (3==sscanf(uri, "%99[^:/]://%255[^/]/%2047s", scheme_buf, hostname_buf, path_buf+1)) { ok = true; }
else if (2==sscanf(uri, "%99[^:/]://%255[^/]", scheme_buf, hostname_buf)) { ok = true; }
- char* end = port_buf;
- int port_tmp = strtoul(port_buf, &end, 10);
- if (*end != 0)
+ bool success = false;
+ int port_tmp = -1;
+ if (port_buf[0])
{
- // there are invalid characters in port_buf
- return false;
+ port_tmp = StringConvert::ToUInt32(port_buf, UINT32_MAX, 10, &success);
+ if (!success || port_tmp > 65535)
+ {
+ // there are invalid characters in port_buf
+ return false;
+ }
}
if (ok)
diff --git a/source/Utility/UriParser.h b/source/Utility/UriParser.h
index c46628d3bd68..fb129eaf79d5 100644
--- a/source/Utility/UriParser.h
+++ b/source/Utility/UriParser.h
@@ -20,6 +20,14 @@
class UriParser
{
public:
+ // Parses
+ // RETURN VALUE
+ // if url is valid, function returns true and
+ // scheme/hostname/port/path are set to the parsed values
+ // port it set to -1 if it is not included in the URL
+ //
+ // if the url is invalid, function returns false and
+ // output parameters remain unchanged
static bool Parse(const char* uri,
std::string& scheme,
std::string& hostname,
diff --git a/tools/compact-unwind/compact-unwind-dumper.c b/tools/compact-unwind/compact-unwind-dumper.c
index fd8ea2161896..0f898dbc76b4 100644
--- a/tools/compact-unwind/compact-unwind-dumper.c
+++ b/tools/compact-unwind/compact-unwind-dumper.c
@@ -495,7 +495,14 @@ print_encoding_x86_64 (struct baton baton, uint8_t *function_start, uint32_t enc
printf ("large stack ");
}
- printf ("frameless function: stack size %d, register count %d ", stack_size * 8, register_count);
+ if (mode == UNWIND_X86_64_MODE_STACK_IND)
+ {
+ printf ("frameless function: stack size %d, register count %d ", stack_size * 8, register_count);
+ }
+ else
+ {
+ printf ("frameless function: stack size %d, register count %d ", stack_size, register_count);
+ }
if (register_count == 0)
{
@@ -591,7 +598,14 @@ print_encoding_x86_64 (struct baton baton, uint8_t *function_start, uint32_t enc
}
- printf (" CFA is rsp+%d ", stack_size * 8);
+ if (mode == UNWIND_X86_64_MODE_STACK_IND)
+ {
+ printf (" CFA is rsp+%d ", stack_size);
+ }
+ else
+ {
+ printf (" CFA is rsp+%d ", stack_size * 8);
+ }
uint32_t saved_registers_offset = 1;
printf (" rip=[CFA-%d]", saved_registers_offset * 8);
@@ -605,24 +619,29 @@ print_encoding_x86_64 (struct baton baton, uint8_t *function_start, uint32_t enc
break;
case UNWIND_X86_64_REG_RBX:
printf (" rbx=[CFA-%d]", saved_registers_offset * 8);
+ saved_registers_offset++;
break;
case UNWIND_X86_64_REG_R12:
printf (" r12=[CFA-%d]", saved_registers_offset * 8);
+ saved_registers_offset++;
break;
case UNWIND_X86_64_REG_R13:
printf (" r13=[CFA-%d]", saved_registers_offset * 8);
+ saved_registers_offset++;
break;
case UNWIND_X86_64_REG_R14:
printf (" r14=[CFA-%d]", saved_registers_offset * 8);
+ saved_registers_offset++;
break;
case UNWIND_X86_64_REG_R15:
printf (" r15=[CFA-%d]", saved_registers_offset * 8);
+ saved_registers_offset++;
break;
case UNWIND_X86_64_REG_RBP:
printf (" rbp=[CFA-%d]", saved_registers_offset * 8);
+ saved_registers_offset++;
break;
}
- saved_registers_offset++;
}
}
@@ -712,7 +731,14 @@ print_encoding_i386 (struct baton baton, uint8_t *function_start, uint32_t encod
printf ("large stack ");
}
- printf ("frameless function: stack size %d, register count %d ", stack_size * 4, register_count);
+ if (mode == UNWIND_X86_MODE_STACK_IND)
+ {
+ printf ("frameless function: stack size %d, register count %d ", stack_size, register_count);
+ }
+ else
+ {
+ printf ("frameless function: stack size %d, register count %d ", stack_size * 4, register_count);
+ }
if (register_count == 0)
{
@@ -808,7 +834,14 @@ print_encoding_i386 (struct baton baton, uint8_t *function_start, uint32_t encod
}
- printf (" CFA is esp+%d ", stack_size * 4);
+ if (mode == UNWIND_X86_MODE_STACK_IND)
+ {
+ printf (" CFA is esp+%d ", stack_size);
+ }
+ else
+ {
+ printf (" CFA is esp+%d ", stack_size * 4);
+ }
uint32_t saved_registers_offset = 1;
printf (" eip=[CFA-%d]", saved_registers_offset * 4);
@@ -822,24 +855,29 @@ print_encoding_i386 (struct baton baton, uint8_t *function_start, uint32_t encod
break;
case UNWIND_X86_REG_EBX:
printf (" ebx=[CFA-%d]", saved_registers_offset * 4);
+ saved_registers_offset++;
break;
case UNWIND_X86_REG_ECX:
printf (" ecx=[CFA-%d]", saved_registers_offset * 4);
+ saved_registers_offset++;
break;
case UNWIND_X86_REG_EDX:
printf (" edx=[CFA-%d]", saved_registers_offset * 4);
+ saved_registers_offset++;
break;
case UNWIND_X86_REG_EDI:
printf (" edi=[CFA-%d]", saved_registers_offset * 4);
+ saved_registers_offset++;
break;
case UNWIND_X86_REG_ESI:
printf (" esi=[CFA-%d]", saved_registers_offset * 4);
+ saved_registers_offset++;
break;
case UNWIND_X86_REG_EBP:
printf (" ebp=[CFA-%d]", saved_registers_offset * 4);
+ saved_registers_offset++;
break;
}
- saved_registers_offset++;
}
}
diff --git a/tools/lldb-mi/Driver.cpp b/tools/lldb-mi/Driver.cpp
index 34a2471e9672..2a907636723b 100644
--- a/tools/lldb-mi/Driver.cpp
+++ b/tools/lldb-mi/Driver.cpp
@@ -27,17 +27,17 @@
#ifdef _MSC_VER
#include <lldb\Host\windows\getopt\GetOptInc.h>
#endif // _MSC_VER
-#include <lldb/API/SBBreakpoint.h>
-#include <lldb/API/SBCommandInterpreter.h>
-#include <lldb/API/SBCommandReturnObject.h>
-#include <lldb/API/SBCommunication.h>
-#include <lldb/API/SBEvent.h>
-#include <lldb/API/SBHostOS.h>
-#include <lldb/API/SBListener.h>
-#include <lldb/API/SBStream.h>
-#include <lldb/API/SBTarget.h>
-#include <lldb/API/SBThread.h>
-#include <lldb/API/SBProcess.h>
+#include "lldb/API/SBBreakpoint.h"
+#include "lldb/API/SBCommandInterpreter.h"
+#include "lldb/API/SBCommandReturnObject.h"
+#include "lldb/API/SBCommunication.h"
+#include "lldb/API/SBEvent.h"
+#include "lldb/API/SBHostOS.h"
+#include "lldb/API/SBListener.h"
+#include "lldb/API/SBStream.h"
+#include "lldb/API/SBTarget.h"
+#include "lldb/API/SBThread.h"
+#include "lldb/API/SBProcess.h"
using namespace lldb;
diff --git a/tools/lldb-mi/Driver.h b/tools/lldb-mi/Driver.h
index 41fc21da407e..5bc97383a0c1 100644
--- a/tools/lldb-mi/Driver.h
+++ b/tools/lldb-mi/Driver.h
@@ -15,17 +15,17 @@
#define lldb_Driver_h_
//#include "Platform.h" // IOR removed
-#include <lldb/Utility/PseudoTerminal.h>
+#include "lldb/Utility/PseudoTerminal.h"
#include <set>
#include <bitset>
#include <string>
#include <vector>
-#include <lldb/API/SBDefines.h>
-#include <lldb/API/SBBroadcaster.h>
-#include <lldb/API/SBDebugger.h>
-#include <lldb/API/SBError.h>
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBBroadcaster.h"
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBError.h"
#include "MIDriverMgr.h"
#include "MIDriverBase.h"
diff --git a/tools/lldb-mi/MICmdArgValConsume.cpp b/tools/lldb-mi/MICmdArgValConsume.cpp
index 3a01db4bc4f8..041005567393 100644
--- a/tools/lldb-mi/MICmdArgValConsume.cpp
+++ b/tools/lldb-mi/MICmdArgValConsume.cpp
@@ -73,31 +73,22 @@ CMICmdArgValConsume::Validate(CMICmdArgContext &vwArgContext)
if (vwArgContext.IsEmpty())
return MIstatus::success;
- if (vwArgContext.GetNumberArgsPresent() == 1)
- {
- const CMIUtilString &rArg(vwArgContext.GetArgsLeftToParse());
- m_bFound = true;
- m_bValid = true;
- vwArgContext.RemoveArg(rArg);
- return MIstatus::success;
- }
-
- // In reality there are more than one option, if so the file option
- // is the last one (don't handle that here - find the best looking one)
+ // Consume the optional file, line, linenum arguments till the mode '--' argument
const CMIUtilString::VecString_t vecOptions(vwArgContext.GetArgs());
CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
while (it != vecOptions.end())
{
- const CMIUtilString &rTxt(*it);
- m_bFound = true;
-
- if (vwArgContext.RemoveArg(rTxt))
+ const CMIUtilString & rTxt( *it );
+
+ if ( rTxt.compare( "--" ) == 0 )
{
+ m_bFound = true;
m_bValid = true;
- return MIstatus::success;
- }
- else
- return MIstatus::success;
+ return MIstatus::success;
+ }
+
+ if ( !vwArgContext.RemoveArg( rTxt ) )
+ return MIstatus::failure;
// Next
++it;
diff --git a/tools/lldb-mi/MICmdCmd.h b/tools/lldb-mi/MICmdCmd.h
index b51318fa9dff..1fd363084b4a 100644
--- a/tools/lldb-mi/MICmdCmd.h
+++ b/tools/lldb-mi/MICmdCmd.h
@@ -38,8 +38,8 @@ MI commands implemented are:
// Third party headers:
#include <vector>
-#include <lldb/API/SBBreakpoint.h>
-#include <lldb/API/SBCommandReturnObject.h>
+#include "lldb/API/SBBreakpoint.h"
+#include "lldb/API/SBCommandReturnObject.h"
// In-house headers:
#include "MICmdBase.h"
diff --git a/tools/lldb-mi/MICmdCmdBreak.cpp b/tools/lldb-mi/MICmdCmdBreak.cpp
index c338cf0a363d..9ad7ea3540fd 100644
--- a/tools/lldb-mi/MICmdCmdBreak.cpp
+++ b/tools/lldb-mi/MICmdCmdBreak.cpp
@@ -25,7 +25,7 @@
//--
// Third Party Headers:
-#include <lldb/API/SBBreakpointLocation.h>
+#include "lldb/API/SBBreakpointLocation.h"
// In-house headers:
#include "MICmdCmdBreak.h"
@@ -180,19 +180,16 @@ CMICmdCmdBreakInsert::Execute(void)
CMIUtilString fileName;
MIuint nFileLine = 0;
CMIUtilString strFileFn;
- const MIint nPosColon = m_brkName.find(cColon);
- if (nPosColon != (MIint)std::string::npos)
+ CMIUtilString rStrLineOrFn;
+ // Full path in windows can have : after drive letter. So look for the
+ // last colon
+ const size_t nPosColon = m_brkName.find_last_of(cColon);
+ if (nPosColon != std::string::npos)
{
- CMIUtilString::VecString_t vecFileAndLocation;
- const MIuint nSplits = m_brkName.Split(cColon, vecFileAndLocation);
- MIunused(nSplits);
- if (vecFileAndLocation.size() != 2)
- {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_LOCATION_FORMAT), m_cmdData.strMiCmd.c_str(), m_brkName.c_str()));
- return MIstatus::failure;
- }
- fileName = vecFileAndLocation.at(0);
- const CMIUtilString &rStrLineOrFn(vecFileAndLocation.at(1));
+ // extract file name and line number from it
+ fileName = m_brkName.substr(0, nPosColon);
+ rStrLineOrFn = m_brkName.substr(nPosColon + 1, m_brkName.size() - nPosColon - 1);
+
if (rStrLineOrFn.empty())
eBrkPtType = eBreakPoint_ByName;
else
@@ -232,20 +229,20 @@ CMICmdCmdBreakInsert::Execute(void)
// Ask LLDB to create a breakpoint
bool bOk = MIstatus::success;
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBTarget &rTarget = rSessionInfo.m_lldbTarget;
+ lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
switch (eBrkPtType)
{
case eBreakPoint_ByAddress:
- m_brkPt = rTarget.BreakpointCreateByAddress(nAddress);
+ m_brkPt = sbTarget.BreakpointCreateByAddress(nAddress);
break;
case eBreakPoint_ByFileFn:
- m_brkPt = rTarget.BreakpointCreateByName(strFileFn.c_str(), fileName.c_str());
+ m_brkPt = sbTarget.BreakpointCreateByName(strFileFn.c_str(), fileName.c_str());
break;
case eBreakPoint_ByFileLine:
- m_brkPt = rTarget.BreakpointCreateByLocation(fileName.c_str(), nFileLine);
+ m_brkPt = sbTarget.BreakpointCreateByLocation(fileName.c_str(), nFileLine);
break;
case eBreakPoint_ByName:
- m_brkPt = rTarget.BreakpointCreateByName(m_brkName.c_str(), rTarget.GetExecutable().GetFilename());
+ m_brkPt = sbTarget.BreakpointCreateByName(m_brkName.c_str(), sbTarget.GetExecutable().GetFilename());
break;
case eBreakPoint_count:
case eBreakPoint_NotDefineYet:
@@ -327,7 +324,7 @@ CMICmdCmdBreakInsert::Acknowledge(void)
sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp;
sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;
- sBrkPtInfo.m_nTimes = m_brkPt.GetNumLocations();
+ sBrkPtInfo.m_nTimes = m_brkPt.GetHitCount();
sBrkPtInfo.m_strOrigLoc = m_brkName;
sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
@@ -440,7 +437,7 @@ CMICmdCmdBreakDelete::Execute(void)
}
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- const bool bBrkPt = rSessionInfo.m_lldbTarget.BreakpointDelete(static_cast<lldb::break_id_t>(nBrk));
+ const bool bBrkPt = rSessionInfo.GetTarget().BreakpointDelete(static_cast<lldb::break_id_t>(nBrk));
if (!bBrkPt)
{
const CMIUtilString strBrkNum(CMIUtilString::Format("%d", nBrk));
@@ -560,7 +557,7 @@ CMICmdCmdBreakDisable::Execute(void)
}
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID(static_cast<lldb::break_id_t>(nBrk));
+ lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(static_cast<lldb::break_id_t>(nBrk));
if (brkPt.IsValid())
{
m_bBrkPtDisabledOk = true;
@@ -700,7 +697,7 @@ CMICmdCmdBreakEnable::Execute(void)
}
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID(static_cast<lldb::break_id_t>(nBrk));
+ lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(static_cast<lldb::break_id_t>(nBrk));
if (brkPt.IsValid())
{
m_bBrkPtEnabledOk = true;
@@ -837,7 +834,7 @@ CMICmdCmdBreakAfter::Execute(void)
m_nBrkPtCount = pArgCount->GetValue();
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID(static_cast<lldb::break_id_t>(m_nBrkPtId));
+ lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(static_cast<lldb::break_id_t>(m_nBrkPtId));
if (brkPt.IsValid())
{
brkPt.SetIgnoreCount(m_nBrkPtCount);
@@ -972,7 +969,7 @@ CMICmdCmdBreakCondition::Execute(void)
m_strBrkPtExpr += GetRestOfExpressionNotSurroundedInQuotes();
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID(static_cast<lldb::break_id_t>(m_nBrkPtId));
+ lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(static_cast<lldb::break_id_t>(m_nBrkPtId));
if (brkPt.IsValid())
{
brkPt.SetCondition(m_strBrkPtExpr.c_str());
diff --git a/tools/lldb-mi/MICmdCmdBreak.h b/tools/lldb-mi/MICmdCmdBreak.h
index c9540b0521eb..371afa15b639 100644
--- a/tools/lldb-mi/MICmdCmdBreak.h
+++ b/tools/lldb-mi/MICmdCmdBreak.h
@@ -36,7 +36,7 @@
#pragma once
// Third party headers:
-#include <lldb/API/SBBreakpoint.h>
+#include "lldb/API/SBBreakpoint.h"
// In-house headers:
#include "MICmdBase.h"
diff --git a/tools/lldb-mi/MICmdCmdData.cpp b/tools/lldb-mi/MICmdCmdData.cpp
index e1abe83b9165..92e419073335 100644
--- a/tools/lldb-mi/MICmdCmdData.cpp
+++ b/tools/lldb-mi/MICmdCmdData.cpp
@@ -28,10 +28,10 @@
//--
// Third Party Headers:
-#include <lldb/API/SBThread.h>
-#include <lldb/API/SBInstruction.h>
-#include <lldb/API/SBInstructionList.h>
-#include <lldb/API/SBStream.h>
+#include "lldb/API/SBThread.h"
+#include "lldb/API/SBInstruction.h"
+#include "lldb/API/SBInstructionList.h"
+#include "lldb/API/SBStream.h"
// In-house headers:
#include "MICmdCmdData.h"
@@ -122,22 +122,22 @@ CMICmdCmdDataEvaluateExpression::Execute(void)
const CMIUtilString &rExpression(pArgExpr->GetValue());
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess &rProcess = rSessionInfo.m_lldbProcess;
- lldb::SBThread thread = rProcess.GetSelectedThread();
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
+ lldb::SBThread thread = sbProcess.GetSelectedThread();
m_bExpressionValid = (thread.GetNumFrames() > 0);
if (!m_bExpressionValid)
return MIstatus::success;
lldb::SBFrame frame = thread.GetSelectedFrame();
lldb::SBValue value = frame.EvaluateExpression(rExpression.c_str());
- if (!value.IsValid())
+ if (!value.IsValid() || value.GetError().Fail())
value = frame.FindVariable(rExpression.c_str());
- if (!value.IsValid())
+ const CMICmnLLDBUtilSBValue utilValue(value);
+ if (!utilValue.IsValid() || utilValue.IsValueUnknown())
{
m_bEvaluatedExpression = false;
return MIstatus::success;
}
- const CMICmnLLDBUtilSBValue utilValue(value);
if (!utilValue.HasName())
{
if (HaveInvalidCharacterInExpression(rExpression, m_cExpressionInvalidChar))
@@ -279,16 +279,10 @@ CMICmdCmdDataEvaluateExpression::CreateSelf(void)
bool
CMICmdCmdDataEvaluateExpression::HaveInvalidCharacterInExpression(const CMIUtilString &vrExpr, MIchar &vrwInvalidChar)
{
- bool bFoundInvalidCharInExpression = false;
- vrwInvalidChar = 0x00;
-
- if (vrExpr.at(0) == '\\')
- {
- // Example: Mouse hover over "%5d" expression has \"%5d\" in it
- bFoundInvalidCharInExpression = true;
- vrwInvalidChar = '\\';
- }
-
+ static const std::string strInvalidCharacters(";#\\");
+ const size_t nInvalidCharacterOffset = vrExpr.find_first_of(strInvalidCharacters);
+ const bool bFoundInvalidCharInExpression = (nInvalidCharacterOffset != CMIUtilString::npos);
+ vrwInvalidChar = bFoundInvalidCharInExpression ? vrExpr[nInvalidCharacterOffset] : 0x00;
return bFoundInvalidCharInExpression;
}
@@ -342,7 +336,7 @@ bool
CMICmdCmdDataDisassemble::ParseArgs(void)
{
bool bOk =
- m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1)));
+ m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
bOk = bOk &&
m_setCmdArgs.Add(
*(new CMICmdArgValOptionShort(m_constStrArgAddrStart, true, true, CMICmdArgValListBase::eArgValType_StringQuotedNumber, 1)));
@@ -373,7 +367,7 @@ CMICmdCmdDataDisassemble::Execute(void)
// Retrieve the --thread option's thread ID (only 1)
MIuint64 nThreadId = UINT64_MAX;
- if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
+ if (pArgThread->GetFound() && !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str()));
return MIstatus::failure;
@@ -410,23 +404,24 @@ CMICmdCmdDataDisassemble::Execute(void)
const MIuint nDisasmMode = pArgMode->GetValue();
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBTarget &rTarget = rSessionInfo.m_lldbTarget;
+ lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
lldb::addr_t lldbStartAddr = static_cast<lldb::addr_t>(nAddrStart);
- lldb::SBInstructionList instructions = rTarget.ReadInstructions(lldb::SBAddress(lldbStartAddr, rTarget), nAddrEnd - nAddrStart);
+ lldb::SBInstructionList instructions = sbTarget.ReadInstructions(lldb::SBAddress(lldbStartAddr, sbTarget), nAddrEnd - nAddrStart);
const MIuint nInstructions = instructions.GetSize();
for (size_t i = 0; i < nInstructions; i++)
{
const MIchar *pUnknown = "??";
lldb::SBInstruction instrt = instructions.GetInstructionAtIndex(i);
- const MIchar *pStrMnemonic = instrt.GetMnemonic(rTarget);
+ const MIchar *pStrMnemonic = instrt.GetMnemonic(sbTarget);
pStrMnemonic = (pStrMnemonic != nullptr) ? pStrMnemonic : pUnknown;
lldb::SBAddress address = instrt.GetAddress();
- lldb::addr_t addr = address.GetLoadAddress(rTarget);
+ lldb::addr_t addr = address.GetLoadAddress(sbTarget);
const MIchar *pFnName = address.GetFunction().GetName();
pFnName = (pFnName != nullptr) ? pFnName : pUnknown;
lldb::addr_t addrOffSet = address.GetOffset();
- const MIchar *pStrOperands = instrt.GetOperands(rTarget);
+ const MIchar *pStrOperands = instrt.GetOperands(sbTarget);
pStrOperands = (pStrOperands != nullptr) ? pStrOperands : pUnknown;
+ const size_t instrtSize = instrt.GetByteSize();
// MI "{address=\"0x%08llx\",func-name=\"%s\",offset=\"%lld\",inst=\"%s %s\"}"
const CMICmnMIValueConst miValueConst(CMIUtilString::Format("0x%08llx", addr));
@@ -438,9 +433,12 @@ CMICmdCmdDataDisassemble::Execute(void)
const CMICmnMIValueConst miValueConst3(CMIUtilString::Format("0x%lld", addrOffSet));
const CMICmnMIValueResult miValueResult3("offset", miValueConst3);
miValueTuple.Add(miValueResult3);
- const CMICmnMIValueConst miValueConst4(CMIUtilString::Format("%s %s", pStrMnemonic, pStrOperands));
- const CMICmnMIValueResult miValueResult4("inst", miValueConst4);
+ const CMICmnMIValueConst miValueConst4(CMIUtilString::Format("%d", instrtSize));
+ const CMICmnMIValueResult miValueResult4("size", miValueConst4);
miValueTuple.Add(miValueResult4);
+ const CMICmnMIValueConst miValueConst5(CMIUtilString::Format("%s %s", pStrMnemonic, pStrOperands));
+ const CMICmnMIValueResult miValueResult5("inst", miValueConst5);
+ miValueTuple.Add(miValueResult5);
if (nDisasmMode == 1)
{
@@ -599,9 +597,9 @@ CMICmdCmdDataReadMemoryBytes::Execute(void)
}
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess &rProcess = rSessionInfo.m_lldbProcess;
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
lldb::SBError error;
- const MIuint64 nReadBytes = rProcess.ReadMemory(static_cast<lldb::addr_t>(nAddrStart), (void *)m_pBufferMemory, nAddrNumBytes, error);
+ const MIuint64 nReadBytes = sbProcess.ReadMemory(static_cast<lldb::addr_t>(nAddrStart), (void *)m_pBufferMemory, nAddrNumBytes, error);
if (nReadBytes != nAddrNumBytes)
{
SetError(
@@ -826,30 +824,58 @@ CMICmdCmdDataListRegisterNames::ParseArgs(void)
bool
CMICmdCmdDataListRegisterNames::Execute(void)
{
+ CMICMDBASE_GETOPTION(pArgRegNo, ListOfN, m_constStrArgRegNo);
+
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess &rProcess = rSessionInfo.m_lldbProcess;
- if (!rProcess.IsValid())
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
+ if (!sbProcess.IsValid())
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS), m_cmdData.strMiCmd.c_str()));
return MIstatus::failure;
}
- lldb::SBThread thread = rProcess.GetSelectedThread();
- lldb::SBFrame frame = thread.GetSelectedFrame();
- lldb::SBValueList registers = frame.GetRegisters();
- const MIuint nRegisters = registers.GetSize();
- for (MIuint i = 0; i < nRegisters; i++)
+ const CMICmdArgValListBase::VecArgObjPtr_t &rVecRegNo(pArgRegNo->GetExpectedOptions());
+ if (!rVecRegNo.empty())
{
- lldb::SBValue value = registers.GetValueAtIndex(i);
- const MIuint nRegChildren = value.GetNumChildren();
- for (MIuint j = 0; j < nRegChildren; j++)
+ // List of required registers
+ CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecRegNo.begin();
+ while (it != rVecRegNo.end())
{
- lldb::SBValue value2 = value.GetChildAtIndex(j);
- if (value2.IsValid())
+ const CMICmdArgValNumber *pRegNo = static_cast<CMICmdArgValNumber *>(*it);
+ const MIuint nRegIndex = pRegNo->GetValue();
+ lldb::SBValue regValue = GetRegister(nRegIndex);
+ if (regValue.IsValid())
{
- const CMICmnMIValueConst miValueConst(CMICmnLLDBUtilSBValue(value2).GetName());
+ const CMICmnMIValueConst miValueConst(CMICmnLLDBUtilSBValue(regValue).GetName());
m_miValueList.Add(miValueConst);
}
+
+ // Next
+ ++it;
+ }
+ }
+ else
+ {
+ // List of all registers
+ lldb::SBThread thread = sbProcess.GetSelectedThread();
+ lldb::SBFrame frame = thread.GetSelectedFrame();
+ lldb::SBValueList registers = frame.GetRegisters();
+ const MIuint nRegisters = registers.GetSize();
+ for (MIuint i = 0; i < nRegisters; i++)
+ {
+ lldb::SBValue value = registers.GetValueAtIndex(i);
+ const MIuint nRegChildren = value.GetNumChildren();
+ for (MIuint j = 0; j < nRegChildren; j++)
+ {
+ lldb::SBValue regValue = value.GetChildAtIndex(j);
+ if (regValue.IsValid())
+ {
+ const CMICmnMIValueConst miValueConst(CMICmnLLDBUtilSBValue(regValue).GetName());
+ const bool bOk = m_miValueList.Add(miValueConst);
+ if (!bOk)
+ return MIstatus::failure;
+ }
+ }
}
}
@@ -889,6 +915,42 @@ CMICmdCmdDataListRegisterNames::CreateSelf(void)
return new CMICmdCmdDataListRegisterNames();
}
+//++ ------------------------------------------------------------------------------------
+// Details: Required by the CMICmdFactory when registering *this command. The factory
+// calls this function to create an instance of *this command.
+// Type: Method.
+// Args: None.
+// Return: lldb::SBValue - LLDB SBValue object.
+// Throws: None.
+//--
+lldb::SBValue
+CMICmdCmdDataListRegisterNames::GetRegister(const MIuint vRegisterIndex) const
+{
+ lldb::SBThread thread = CMICmnLLDBDebugSessionInfo::Instance().GetProcess().GetSelectedThread();
+ lldb::SBFrame frame = thread.GetSelectedFrame();
+ lldb::SBValueList registers = frame.GetRegisters();
+ const MIuint nRegisters = registers.GetSize();
+ MIuint nRegisterIndex(vRegisterIndex);
+ for (MIuint i = 0; i < nRegisters; i++)
+ {
+ lldb::SBValue value = registers.GetValueAtIndex(i);
+ const MIuint nRegChildren = value.GetNumChildren();
+ if (nRegisterIndex >= nRegChildren)
+ {
+ nRegisterIndex -= nRegChildren;
+ continue;
+ }
+
+ lldb::SBValue value2 = value.GetChildAtIndex(nRegisterIndex);
+ if (value2.IsValid())
+ {
+ return value2;
+ }
+ }
+
+ return lldb::SBValue();
+}
+
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
@@ -906,7 +968,6 @@ CMICmdCmdDataListRegisterValues::CMICmdCmdDataListRegisterValues(void)
, m_constStrArgFormat("fmt")
, m_constStrArgRegNo("regno")
, m_miValueList(true)
- , m_pProcess(nullptr)
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "data-list-register-values";
@@ -975,33 +1036,60 @@ CMICmdCmdDataListRegisterValues::Execute(void)
}
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess &rProcess = rSessionInfo.m_lldbProcess;
- if (!rProcess.IsValid())
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
+ if (!sbProcess.IsValid())
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS), m_cmdData.strMiCmd.c_str()));
return MIstatus::failure;
}
- m_pProcess = &rProcess;
const CMICmdArgValListBase::VecArgObjPtr_t &rVecRegNo(pArgRegNo->GetExpectedOptions());
- CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecRegNo.begin();
- while (it != rVecRegNo.end())
+ if (!rVecRegNo.empty())
{
- const CMICmdArgValNumber *pRegNo = static_cast<CMICmdArgValNumber *>(*it);
- const MIuint nReg = pRegNo->GetValue();
- lldb::SBValue regValue = GetRegister(nReg);
- const CMIUtilString strRegValue(CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(regValue, eFormat));
-
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%u", nReg));
- const CMICmnMIValueResult miValueResult("number", miValueConst);
- CMICmnMIValueTuple miValueTuple(miValueResult);
- const CMICmnMIValueConst miValueConst2(strRegValue);
- const CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
- m_miValueList.Add(miValueTuple);
+ // List of required registers
+ CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecRegNo.begin();
+ while (it != rVecRegNo.end())
+ {
+ const CMICmdArgValNumber *pRegNo = static_cast<CMICmdArgValNumber *>(*it);
+ const MIuint nRegIndex = pRegNo->GetValue();
+ lldb::SBValue regValue = GetRegister(nRegIndex);
+ if (regValue.IsValid())
+ {
+ const bool bOk = AddToOutput(nRegIndex, regValue, eFormat);
+ if (!bOk)
+ return MIstatus::failure;
+ }
- // Next
- ++it;
+ // Next
+ ++it;
+ }
+ }
+ else
+ {
+ // No register numbers are provided. Output all registers.
+ lldb::SBThread thread = sbProcess.GetSelectedThread();
+ lldb::SBFrame frame = thread.GetSelectedFrame();
+ lldb::SBValueList registers = frame.GetRegisters();
+ const MIuint nRegisters = registers.GetSize();
+ MIuint nRegIndex = 0;
+ for (MIuint i = 0; i < nRegisters; i++)
+ {
+ lldb::SBValue value = registers.GetValueAtIndex(i);
+ const MIuint nRegChildren = value.GetNumChildren();
+ for (MIuint j = 0; j < nRegChildren; j++)
+ {
+ lldb::SBValue regValue = value.GetChildAtIndex(j);
+ if (regValue.IsValid())
+ {
+ const bool bOk = AddToOutput(nRegIndex, regValue, eFormat);
+ if (!bOk)
+ return MIstatus::failure;
+ }
+
+ // Next
+ ++nRegIndex;
+ }
+ }
}
return MIstatus::success;
@@ -1051,27 +1139,52 @@ CMICmdCmdDataListRegisterValues::CreateSelf(void)
lldb::SBValue
CMICmdCmdDataListRegisterValues::GetRegister(const MIuint vRegisterIndex) const
{
- lldb::SBThread thread = m_pProcess->GetSelectedThread();
+ lldb::SBThread thread = CMICmnLLDBDebugSessionInfo::Instance().GetProcess().GetSelectedThread();
lldb::SBFrame frame = thread.GetSelectedFrame();
lldb::SBValueList registers = frame.GetRegisters();
const MIuint nRegisters = registers.GetSize();
+ MIuint nRegisterIndex(vRegisterIndex);
for (MIuint i = 0; i < nRegisters; i++)
{
lldb::SBValue value = registers.GetValueAtIndex(i);
const MIuint nRegChildren = value.GetNumChildren();
- if (nRegChildren > 0)
+ if (nRegisterIndex >= nRegChildren)
{
- lldb::SBValue value2 = value.GetChildAtIndex(vRegisterIndex);
- if (value2.IsValid())
- {
- return value2;
- }
+ nRegisterIndex -= nRegChildren;
+ continue;
+ }
+
+ lldb::SBValue value2 = value.GetChildAtIndex(nRegisterIndex);
+ if (value2.IsValid())
+ {
+ return value2;
}
}
return lldb::SBValue();
}
+//++ ------------------------------------------------------------------------------------
+// Details: Adds the register value to the output list.
+// Type: Method.
+// Args: Value of the register, its index and output format.
+// Return: None
+// Throws: None.
+//--
+bool
+CMICmdCmdDataListRegisterValues::AddToOutput(const MIuint vnIndex, const lldb::SBValue &vrValue,
+ CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veVarFormat)
+{
+ const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%u", vnIndex));
+ const CMICmnMIValueResult miValueResult("number", miValueConst);
+ CMICmnMIValueTuple miValueTuple(miValueResult);
+ const CMIUtilString strRegValue(CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(vrValue, veVarFormat));
+ const CMICmnMIValueConst miValueConst2(strRegValue);
+ const CMICmnMIValueResult miValueResult2("value", miValueConst2);
+ bool bOk = miValueTuple.Add(miValueResult2);
+ return bOk && m_miValueList.Add(miValueTuple);
+}
+
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
@@ -1371,10 +1484,10 @@ CMICmdCmdDataWriteMemory::Execute(void)
*m_pBufferMemory = static_cast<MIchar>(nValue);
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess &rProcess = rSessionInfo.m_lldbProcess;
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
lldb::SBError error;
lldb::addr_t addr = static_cast<lldb::addr_t>(m_nAddr + nAddrOffset);
- const size_t nBytesWritten = rProcess.WriteMemory(addr, (const void *)m_pBufferMemory, (size_t)m_nCount, error);
+ const size_t nBytesWritten = sbProcess.WriteMemory(addr, (const void *)m_pBufferMemory, (size_t)m_nCount, error);
if (nBytesWritten != static_cast<size_t>(m_nCount))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDB_ERR_NOT_WRITE_WHOLEBLK), m_cmdData.strMiCmd.c_str(), m_nCount, addr));
diff --git a/tools/lldb-mi/MICmdCmdData.h b/tools/lldb-mi/MICmdCmdData.h
index 74ceeb8581b9..5084beea6d8f 100644
--- a/tools/lldb-mi/MICmdCmdData.h
+++ b/tools/lldb-mi/MICmdCmdData.h
@@ -42,6 +42,7 @@
#include "MICmdBase.h"
#include "MICmnMIValueTuple.h"
#include "MICmnMIValueList.h"
+#include "MICmnLLDBDebugSessionInfoVarObj.h"
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
@@ -218,6 +219,10 @@ class CMICmdCmdDataListRegisterNames : public CMICmdBase
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdDataListRegisterNames(void);
+ // Methods:
+ private:
+ lldb::SBValue GetRegister(const MIuint vRegisterIndex) const;
+
// Attributes:
private:
const CMIUtilString m_constStrArgThreadGroup; // Not specified in MI spec but Eclipse gives this option
@@ -255,6 +260,7 @@ class CMICmdCmdDataListRegisterValues : public CMICmdBase
// Methods:
private:
lldb::SBValue GetRegister(const MIuint vRegisterIndex) const;
+ bool AddToOutput(const MIuint vnIndex, const lldb::SBValue &vrValue, CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veVarFormat);
// Attributes:
private:
@@ -263,7 +269,6 @@ class CMICmdCmdDataListRegisterValues : public CMICmdBase
const CMIUtilString m_constStrArgFormat;
const CMIUtilString m_constStrArgRegNo;
CMICmnMIValueList m_miValueList;
- lldb::SBProcess *m_pProcess;
};
//++ ============================================================================
diff --git a/tools/lldb-mi/MICmdCmdExec.cpp b/tools/lldb-mi/MICmdCmdExec.cpp
index 9e1224363f5d..eec62c8d37e8 100644
--- a/tools/lldb-mi/MICmdCmdExec.cpp
+++ b/tools/lldb-mi/MICmdCmdExec.cpp
@@ -27,9 +27,9 @@
//--
// Third Party Headers:
-#include <lldb/API/SBCommandInterpreter.h>
-#include <lldb/API/SBProcess.h>
-#include <lldb/API/SBStream.h>
+#include "lldb/API/SBCommandInterpreter.h"
+#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBStream.h"
#include "lldb/lldb-enumerations.h"
// In-house headers:
@@ -91,8 +91,8 @@ CMICmdCmdExecRun::Execute(void)
lldb::SBError error;
lldb::SBStream errMsg;
uint32_t launch_flags = lldb::LaunchFlags::eLaunchFlagDebug;
- lldb::SBProcess process = rSessionInfo.m_lldbTarget.Launch(rSessionInfo.m_rLlldbListener, nullptr, nullptr, nullptr, nullptr, nullptr,
- nullptr, launch_flags, false, error);
+ lldb::SBProcess process = rSessionInfo.GetTarget().Launch(rSessionInfo.GetListener(), nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, launch_flags, false, error);
if ((!process.IsValid()) || (error.Fail()))
{
@@ -100,9 +100,6 @@ CMICmdCmdExecRun::Execute(void)
return MIstatus::failure;
}
- // Save the process in the session info
- rSessionInfo.m_lldbProcess = process;
-
if (!CMIDriver::Instance().SetDriverStateRunningDebugging())
{
const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription());
@@ -137,7 +134,7 @@ CMICmdCmdExecRun::Acknowledge(void)
m_miResultRecord = miRecordResult;
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::pid_t pid = rSessionInfo.m_lldbProcess.GetProcessID();
+ lldb::pid_t pid = rSessionInfo.GetProcess().GetProcessID();
// Give the client '=thread-group-started,id="i1" pid="xyz"'
m_bHasResultRecordExtra = true;
const CMICmnMIValueConst miValueConst2("i1");
@@ -212,7 +209,7 @@ CMICmdCmdExecContinue::Execute(void)
{
const MIchar *pCmd = "continue";
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- const lldb::ReturnStatus rtn = rSessionInfo.m_rLldbDebugger.GetCommandInterpreter().HandleCommand(pCmd, m_lldbResult);
+ const lldb::ReturnStatus rtn = rSessionInfo.GetDebugger().GetCommandInterpreter().HandleCommand(pCmd, m_lldbResult);
MIunused(rtn);
if (m_lldbResult.GetErrorSize() == 0)
@@ -328,7 +325,7 @@ bool
CMICmdCmdExecNext::ParseArgs(void)
{
bool bOk =
- m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1)));
+ m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNumber, false, false)));
return (bOk && ParseValidateCmdOptions());
}
@@ -349,14 +346,14 @@ CMICmdCmdExecNext::Execute(void)
// Retrieve the --thread option's thread ID (only 1)
MIuint64 nThreadId = UINT64_MAX;
- if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
+ if (pArgThread->GetFound() && !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str()));
return MIstatus::failure;
}
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBDebugger &rDebugger = rSessionInfo.m_rLldbDebugger;
+ lldb::SBDebugger &rDebugger = rSessionInfo.GetDebugger();
CMIUtilString strCmd("thread step-over");
if (nThreadId != UINT64_MAX)
strCmd += CMIUtilString::Format(" %llu", nThreadId);
@@ -455,7 +452,7 @@ bool
CMICmdCmdExecStep::ParseArgs(void)
{
bool bOk =
- m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1)));
+ m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNumber, false, false)));
return (bOk && ParseValidateCmdOptions());
}
@@ -476,14 +473,14 @@ CMICmdCmdExecStep::Execute(void)
// Retrieve the --thread option's thread ID (only 1)
MIuint64 nThreadId = UINT64_MAX;
- if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
+ if (pArgThread->GetFound() && !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str()));
return MIstatus::failure;
}
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBDebugger &rDebugger = rSessionInfo.m_rLldbDebugger;
+ lldb::SBDebugger &rDebugger = rSessionInfo.GetDebugger();
CMIUtilString strCmd("thread step-in");
if (nThreadId != UINT64_MAX)
strCmd += CMIUtilString::Format(" %llu", nThreadId);
@@ -582,7 +579,7 @@ bool
CMICmdCmdExecNextInstruction::ParseArgs(void)
{
bool bOk =
- m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1)));
+ m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNumber, false, false)));
return (bOk && ParseValidateCmdOptions());
}
@@ -603,14 +600,14 @@ CMICmdCmdExecNextInstruction::Execute(void)
// Retrieve the --thread option's thread ID (only 1)
MIuint64 nThreadId = UINT64_MAX;
- if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
+ if (pArgThread->GetFound() && !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str()));
return MIstatus::failure;
}
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBDebugger &rDebugger = rSessionInfo.m_rLldbDebugger;
+ lldb::SBDebugger &rDebugger = rSessionInfo.GetDebugger();
CMIUtilString strCmd("thread step-inst-over");
if (nThreadId != UINT64_MAX)
strCmd += CMIUtilString::Format(" %llu", nThreadId);
@@ -709,7 +706,7 @@ bool
CMICmdCmdExecStepInstruction::ParseArgs(void)
{
bool bOk =
- m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1)));
+ m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNumber, false, false)));
return (bOk && ParseValidateCmdOptions());
}
@@ -730,14 +727,14 @@ CMICmdCmdExecStepInstruction::Execute(void)
// Retrieve the --thread option's thread ID (only 1)
MIuint64 nThreadId = UINT64_MAX;
- if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
+ if (pArgThread->GetFound() && !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str()));
return MIstatus::failure;
}
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBDebugger &rDebugger = rSessionInfo.m_rLldbDebugger;
+ lldb::SBDebugger &rDebugger = rSessionInfo.GetDebugger();
CMIUtilString strCmd("thread step-inst");
if (nThreadId != UINT64_MAX)
strCmd += CMIUtilString::Format(" %llu", nThreadId);
@@ -836,7 +833,7 @@ bool
CMICmdCmdExecFinish::ParseArgs(void)
{
bool bOk =
- m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1)));
+ m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
bOk = bOk &&
m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgFrame, false, false, CMICmdArgValListBase::eArgValType_Number, 1)));
return (bOk && ParseValidateCmdOptions());
@@ -858,14 +855,14 @@ CMICmdCmdExecFinish::Execute(void)
// Retrieve the --thread option's thread ID (only 1)
MIuint64 nThreadId = UINT64_MAX;
- if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
+ if (pArgThread->GetFound() && !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str()));
return MIstatus::failure;
}
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBDebugger &rDebugger = rSessionInfo.m_rLldbDebugger;
+ lldb::SBDebugger &rDebugger = rSessionInfo.GetDebugger();
CMIUtilString strCmd("thread step-out");
if (nThreadId != UINT64_MAX)
strCmd += CMIUtilString::Format(" %llu", nThreadId);
@@ -962,7 +959,7 @@ bool
CMICmdCmdExecInterrupt::Execute(void)
{
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBDebugger &rDebugger = rSessionInfo.m_rLldbDebugger;
+ lldb::SBDebugger &rDebugger = rSessionInfo.GetDebugger();
CMIUtilString strCmd("process interrupt");
const lldb::ReturnStatus status = rDebugger.GetCommandInterpreter().HandleCommand(strCmd.c_str(), m_lldbResult, false);
MIunused(status);
diff --git a/tools/lldb-mi/MICmdCmdExec.h b/tools/lldb-mi/MICmdCmdExec.h
index cf59ec4f5b3e..be03d6b93566 100644
--- a/tools/lldb-mi/MICmdCmdExec.h
+++ b/tools/lldb-mi/MICmdCmdExec.h
@@ -38,7 +38,7 @@
#pragma once
// Third party headers:
-#include <lldb/API/SBCommandReturnObject.h>
+#include "lldb/API/SBCommandReturnObject.h"
// In-house headers:
#include "MICmdBase.h"
diff --git a/tools/lldb-mi/MICmdCmdFile.cpp b/tools/lldb-mi/MICmdCmdFile.cpp
index a954f88dac11..83862f24f1f1 100644
--- a/tools/lldb-mi/MICmdCmdFile.cpp
+++ b/tools/lldb-mi/MICmdCmdFile.cpp
@@ -20,7 +20,7 @@
//--
// Third Party Headers:
-#include <lldb/API/SBStream.h>
+#include "lldb/API/SBStream.h"
// In-house headers:
#include "MICmdCmdFile.h"
@@ -96,7 +96,7 @@ CMICmdCmdFileExecAndSymbols::Execute(void)
CMICmdArgValFile *pArgFile = static_cast<CMICmdArgValFile *>(pArgNamedFile);
const CMIUtilString &strExeFilePath(pArgFile->GetValue());
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBDebugger &rDbgr = rSessionInfo.m_rLldbDebugger;
+ lldb::SBDebugger &rDbgr = rSessionInfo.GetDebugger();
lldb::SBError error;
const MIchar *pTargetTriple = nullptr; // Let LLDB discover the triple required
const MIchar *pTargetPlatformName = "";
@@ -137,8 +137,6 @@ CMICmdCmdFileExecAndSymbols::Execute(void)
return MIstatus::failure;
}
- rSessionInfo.m_lldbTarget = target;
-
return MIstatus::success;
}
diff --git a/tools/lldb-mi/MICmdCmdGdbInfo.cpp b/tools/lldb-mi/MICmdCmdGdbInfo.cpp
index dde6a0b40135..be70962b63ae 100644
--- a/tools/lldb-mi/MICmdCmdGdbInfo.cpp
+++ b/tools/lldb-mi/MICmdCmdGdbInfo.cpp
@@ -20,7 +20,7 @@
//--
// Third party headers:
-#include <lldb/API/SBCommandReturnObject.h>
+#include "lldb/API/SBCommandReturnObject.h"
// In-house headers:
#include "MICmdCmdGdbInfo.h"
@@ -198,11 +198,11 @@ CMICmdCmdGdbInfo::PrintFnSharedLibrary(void)
bool bOk = rStdout.TextToStdout("~\"From To Syms Read Shared Object Library\"");
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBTarget &rTarget = rSessionInfo.m_lldbTarget;
- const MIuint nModules = rTarget.GetNumModules();
+ lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
+ const MIuint nModules = sbTarget.GetNumModules();
for (MIuint i = 0; bOk && (i < nModules); i++)
{
- lldb::SBModule module = rTarget.GetModuleAtIndex(i);
+ lldb::SBModule module = sbTarget.GetModuleAtIndex(i);
if (module.IsValid())
{
const CMIUtilString strModuleFilePath(module.GetFileSpec().GetDirectory());
@@ -216,7 +216,7 @@ CMICmdCmdGdbInfo::PrintFnSharedLibrary(void)
for (MIuint j = 0; j < nSections; j++)
{
lldb::SBSection section = module.GetSectionAtIndex(j);
- lldb::addr_t addrLoad = section.GetLoadAddress(rTarget);
+ lldb::addr_t addrLoad = section.GetLoadAddress(sbTarget);
if (addrLoad != (lldb::addr_t) - 1)
{
if (!bHaveAddrLoad)
diff --git a/tools/lldb-mi/MICmdCmdMiscellanous.cpp b/tools/lldb-mi/MICmdCmdMiscellanous.cpp
index 6b863a8ea8db..4e4e1b986e8a 100644
--- a/tools/lldb-mi/MICmdCmdMiscellanous.cpp
+++ b/tools/lldb-mi/MICmdCmdMiscellanous.cpp
@@ -23,8 +23,8 @@
//--
// Third Party Headers:
-#include <lldb/API/SBCommandInterpreter.h>
-#include <lldb/API/SBThread.h>
+#include "lldb/API/SBCommandInterpreter.h"
+#include "lldb/API/SBThread.h"
// In-house headers:
#include "MICmdCmdMiscellanous.h"
@@ -84,7 +84,7 @@ bool
CMICmdCmdGdbExit::Execute(void)
{
CMICmnLLDBDebugger::Instance().GetDriver().SetExitApplicationFlag(true);
- const lldb::SBError sbErr = m_rLLDBDebugSessionInfo.m_lldbProcess.Detach();
+ const lldb::SBError sbErr = m_rLLDBDebugSessionInfo.GetProcess().Detach();
// Do not check for sbErr.Fail() here, m_lldbProcess is likely !IsValid()
return MIstatus::success;
@@ -234,17 +234,17 @@ CMICmdCmdListThreadGroups::Execute(void)
m_bIsI1 = true;
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess &rProcess = rSessionInfo.m_lldbProcess;
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- // Note do not check for rProcess is IsValid(), continue
+ // Note do not check for sbProcess is IsValid(), continue
m_vecMIValueTuple.clear();
- const MIuint nThreads = rProcess.GetNumThreads();
+ const MIuint nThreads = sbProcess.GetNumThreads();
for (MIuint i = 0; i < nThreads; i++)
{
// GetThreadAtIndex() uses a base 0 index
// GetThreadByIndexID() uses a base 1 index
- lldb::SBThread thread = rProcess.GetThreadAtIndex(i);
+ lldb::SBThread thread = sbProcess.GetThreadAtIndex(i);
if (thread.IsValid())
{
@@ -292,9 +292,9 @@ CMICmdCmdListThreadGroups::Acknowledge(void)
miTuple.Add(miValueResult2);
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- if (rSessionInfo.m_lldbProcess.IsValid())
+ if (rSessionInfo.GetProcess().IsValid())
{
- const lldb::pid_t pid = rSessionInfo.m_lldbProcess.GetProcessID();
+ const lldb::pid_t pid = rSessionInfo.GetProcess().GetProcessID();
const CMIUtilString strPid(CMIUtilString::Format("%lld", pid));
const CMICmnMIValueConst miValueConst3(strPid);
const CMICmnMIValueResult miValueResult3("pid", miValueConst3);
@@ -328,20 +328,20 @@ CMICmdCmdListThreadGroups::Acknowledge(void)
miTuple.Add(miValueResult2);
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- if (rSessionInfo.m_lldbProcess.IsValid())
+ if (rSessionInfo.GetProcess().IsValid())
{
- const lldb::pid_t pid = rSessionInfo.m_lldbProcess.GetProcessID();
+ const lldb::pid_t pid = rSessionInfo.GetProcess().GetProcessID();
const CMIUtilString strPid(CMIUtilString::Format("%lld", pid));
const CMICmnMIValueConst miValueConst3(strPid);
const CMICmnMIValueResult miValueResult3("pid", miValueConst3);
miTuple.Add(miValueResult3);
}
- if (rSessionInfo.m_lldbTarget.IsValid())
+ if (rSessionInfo.GetTarget().IsValid())
{
- lldb::SBTarget &rTrgt = rSessionInfo.m_lldbTarget;
- const MIchar *pDir = rTrgt.GetExecutable().GetDirectory();
- const MIchar *pFileName = rTrgt.GetExecutable().GetFilename();
+ lldb::SBTarget sbTrgt = rSessionInfo.GetTarget();
+ const MIchar *pDir = sbTrgt.GetExecutable().GetDirectory();
+ const MIchar *pFileName = sbTrgt.GetExecutable().GetFilename();
const CMIUtilString strFile(CMIUtilString::Format("%s/%s", pDir, pFileName));
const CMICmnMIValueConst miValueConst4(strFile);
const CMICmnMIValueResult miValueResult4("executable", miValueConst4);
@@ -470,7 +470,7 @@ CMICmdCmdInterpreterExec::Execute(void)
const CMIUtilString &rStrCommand(pArgCommand->GetValue());
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
const lldb::ReturnStatus rtn =
- rSessionInfo.m_rLldbDebugger.GetCommandInterpreter().HandleCommand(rStrCommand.c_str(), m_lldbResult, true);
+ rSessionInfo.GetDebugger().GetCommandInterpreter().HandleCommand(rStrCommand.c_str(), m_lldbResult, true);
MIunused(rtn);
return MIstatus::success;
@@ -588,7 +588,7 @@ CMICmdCmdInferiorTtySet::Execute(void)
bool
CMICmdCmdInferiorTtySet::Acknowledge(void)
{
- const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
+ const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error);
m_miResultRecord = miRecordResult;
return MIstatus::success;
diff --git a/tools/lldb-mi/MICmdCmdMiscellanous.h b/tools/lldb-mi/MICmdCmdMiscellanous.h
index 1cabbac7e80a..fd990940e44d 100644
--- a/tools/lldb-mi/MICmdCmdMiscellanous.h
+++ b/tools/lldb-mi/MICmdCmdMiscellanous.h
@@ -34,7 +34,7 @@
#pragma once
// Third party headers:
-#include <lldb/API/SBCommandReturnObject.h>
+#include "lldb/API/SBCommandReturnObject.h"
// In-house headers:
#include "MICmdBase.h"
diff --git a/tools/lldb-mi/MICmdCmdStack.cpp b/tools/lldb-mi/MICmdCmdStack.cpp
index 4ed6803a1edb..4ab7164a30b7 100644
--- a/tools/lldb-mi/MICmdCmdStack.cpp
+++ b/tools/lldb-mi/MICmdCmdStack.cpp
@@ -23,7 +23,7 @@
//--
// Third Party Headers:
-#include <lldb/API/SBThread.h>
+#include "lldb/API/SBThread.h"
// In-house headers:
#include "MICmdCmdStack.h"
@@ -82,7 +82,7 @@ bool
CMICmdCmdStackInfoDepth::ParseArgs(void)
{
bool bOk =
- m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1)));
+ m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgMaxDepth, false, false)));
return (bOk && ParseValidateCmdOptions());
}
@@ -104,15 +104,15 @@ CMICmdCmdStackInfoDepth::Execute(void)
// Retrieve the --thread option's thread ID (only 1)
MIuint64 nThreadId = UINT64_MAX;
- if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
+ if (pArgThread->GetFound() && !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str()));
return MIstatus::failure;
}
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess &rProcess = rSessionInfo.m_lldbProcess;
- lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID(nThreadId) : rProcess.GetSelectedThread();
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
+ lldb::SBThread thread = (nThreadId != UINT64_MAX) ? sbProcess.GetThreadByIndexID(nThreadId) : sbProcess.GetSelectedThread();
m_nThreadFrames = thread.GetNumFrames();
return MIstatus::success;
@@ -202,7 +202,7 @@ bool
CMICmdCmdStackListFrames::ParseArgs(void)
{
bool bOk =
- m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1)));
+ m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgFrameLow, false, true)));
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgFrameHigh, false, true)));
return (bOk && ParseValidateCmdOptions());
@@ -226,7 +226,7 @@ CMICmdCmdStackListFrames::Execute(void)
// Retrieve the --thread option's thread ID (only 1)
MIuint64 nThreadId = UINT64_MAX;
- if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
+ if (pArgThread->GetFound() && !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str()));
return MIstatus::failure;
@@ -237,8 +237,8 @@ CMICmdCmdStackListFrames::Execute(void)
const MIuint nFrameLow = pArgFrameLow->GetFound() ? pArgFrameLow->GetValue() : 0;
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess &rProcess = rSessionInfo.m_lldbProcess;
- lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID(nThreadId) : rProcess.GetSelectedThread();
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
+ lldb::SBThread thread = (nThreadId != UINT64_MAX) ? sbProcess.GetThreadByIndexID(nThreadId) : sbProcess.GetSelectedThread();
MIuint nThreadFrames = thread.GetNumFrames();
// Adjust nThreadFrames for the nFrameHigh argument as we use nFrameHigh+1 in the min calc as the arg
@@ -350,6 +350,9 @@ CMICmdCmdStackListArguments::CMICmdCmdStackListArguments(void)
, m_miValueList(true)
, m_constStrArgThread("thread")
, m_constStrArgPrintValues("print-values")
+ , m_constStrArgNoValues("no-values")
+ , m_constStrArgAllValues("all-values")
+ , m_constStrArgSimpleValues("simple-values")
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "stack-list-arguments";
@@ -383,7 +386,10 @@ CMICmdCmdStackListArguments::ParseArgs(void)
{
bool bOk =
m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
- bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgPrintValues, true, false)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgPrintValues, false, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgNoValues, false, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgAllValues, false, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgSimpleValues, false, true)));
return (bOk && ParseValidateCmdOptions());
}
@@ -401,6 +407,9 @@ CMICmdCmdStackListArguments::Execute(void)
{
CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
CMICMDBASE_GETOPTION(pArgPrintValues, Number, m_constStrArgPrintValues);
+ CMICMDBASE_GETOPTION(pArgNoValues, OptionLong, m_constStrArgNoValues);
+ CMICMDBASE_GETOPTION(pArgAllValues, OptionLong, m_constStrArgAllValues);
+ CMICMDBASE_GETOPTION(pArgSimpleValues, OptionLong, m_constStrArgSimpleValues);
// Retrieve the --thread option's thread ID (only 1)
MIuint64 nThreadId = UINT64_MAX;
@@ -413,9 +422,32 @@ CMICmdCmdStackListArguments::Execute(void)
}
}
+ CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat;
+ if (pArgPrintValues->GetFound())
+ {
+ const MIuint nPrintValues = pArgPrintValues->GetValue();
+ if (nPrintValues >= CMICmnLLDBDebugSessionInfo::kNumVariableInfoFormats)
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PRINT_VALUES), m_cmdData.strMiCmd.c_str()));
+ return MIstatus::failure;
+ }
+ eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(nPrintValues);
+ }
+ else if (pArgNoValues->GetFound())
+ eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
+ else if (pArgAllValues->GetFound())
+ eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues;
+ else if (pArgSimpleValues->GetFound())
+ eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues;
+ else
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PRINT_VALUES), m_cmdData.strMiCmd.c_str()));
+ return MIstatus::failure;
+ }
+
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess &rProcess = rSessionInfo.m_lldbProcess;
- lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID(nThreadId) : rProcess.GetSelectedThread();
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
+ lldb::SBThread thread = (nThreadId != UINT64_MAX) ? sbProcess.GetThreadByIndexID(nThreadId) : sbProcess.GetSelectedThread();
m_bThreadInvalid = !thread.IsValid();
if (m_bThreadInvalid)
return MIstatus::success;
@@ -433,7 +465,7 @@ CMICmdCmdStackListArguments::Execute(void)
lldb::SBFrame frame = thread.GetFrameAtIndex(i);
CMICmnMIValueList miValueList(true);
const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Arguments;
- if (!rSessionInfo.MIResponseFormVariableInfo3(frame, maskVarTypes, miValueList))
+ if (!rSessionInfo.MIResponseFormVariableInfo3(frame, maskVarTypes, eVarInfoFormat, miValueList))
return MIstatus::failure;
const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", i));
const CMICmnMIValueResult miValueResult("level", miValueConst);
@@ -508,6 +540,9 @@ CMICmdCmdStackListLocals::CMICmdCmdStackListLocals(void)
, m_constStrArgThread("thread")
, m_constStrArgFrame("frame")
, m_constStrArgPrintValues("print-values")
+ , m_constStrArgNoValues("no-values")
+ , m_constStrArgAllValues("all-values")
+ , m_constStrArgSimpleValues("simple-values")
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "stack-list-locals";
@@ -543,7 +578,10 @@ CMICmdCmdStackListLocals::ParseArgs(void)
m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
bOk = bOk &&
m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgFrame, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
- bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgPrintValues, true, false)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgPrintValues, false, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgNoValues, false, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgAllValues, false, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgSimpleValues, false, true)));
return (bOk && ParseValidateCmdOptions());
}
@@ -561,6 +599,10 @@ CMICmdCmdStackListLocals::Execute(void)
{
CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
+ CMICMDBASE_GETOPTION(pArgPrintValues, Number, m_constStrArgPrintValues);
+ CMICMDBASE_GETOPTION(pArgNoValues, OptionLong, m_constStrArgNoValues);
+ CMICMDBASE_GETOPTION(pArgAllValues, OptionLong, m_constStrArgAllValues);
+ CMICMDBASE_GETOPTION(pArgSimpleValues, OptionLong, m_constStrArgSimpleValues);
// Retrieve the --thread option's thread ID (only 1)
MIuint64 nThreadId = UINT64_MAX;
@@ -572,6 +614,7 @@ CMICmdCmdStackListLocals::Execute(void)
return MIstatus::failure;
}
}
+
MIuint64 nFrame = UINT64_MAX;
if (pArgFrame->GetFound())
{
@@ -582,9 +625,32 @@ CMICmdCmdStackListLocals::Execute(void)
}
}
+ CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat;
+ if (pArgPrintValues->GetFound())
+ {
+ const MIuint nPrintValues = pArgPrintValues->GetValue();
+ if (nPrintValues >= CMICmnLLDBDebugSessionInfo::kNumVariableInfoFormats)
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PRINT_VALUES), m_cmdData.strMiCmd.c_str()));
+ return MIstatus::failure;
+ }
+ eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(nPrintValues);
+ }
+ else if (pArgNoValues->GetFound())
+ eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
+ else if (pArgAllValues->GetFound())
+ eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues;
+ else if (pArgSimpleValues->GetFound())
+ eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues;
+ else
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PRINT_VALUES), m_cmdData.strMiCmd.c_str()));
+ return MIstatus::failure;
+ }
+
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess &rProcess = rSessionInfo.m_lldbProcess;
- lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID(nThreadId) : rProcess.GetSelectedThread();
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
+ lldb::SBThread thread = (nThreadId != UINT64_MAX) ? sbProcess.GetThreadByIndexID(nThreadId) : sbProcess.GetSelectedThread();
m_bThreadInvalid = !thread.IsValid();
if (m_bThreadInvalid)
return MIstatus::success;
@@ -596,12 +662,11 @@ CMICmdCmdStackListLocals::Execute(void)
return MIstatus::success;
}
- const MIuint nFrames = thread.GetNumFrames();
- MIunused(nFrames);
lldb::SBFrame frame = (nFrame != UINT64_MAX) ? thread.GetFrameAtIndex(nFrame) : thread.GetSelectedFrame();
+
CMICmnMIValueList miValueList(true);
const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Locals;
- if (!rSessionInfo.MIResponseFormVariableInfo(frame, maskVarTypes, miValueList))
+ if (!rSessionInfo.MIResponseFormVariableInfo(frame, maskVarTypes, eVarInfoFormat, miValueList))
return MIstatus::failure;
m_miValueList = miValueList;
diff --git a/tools/lldb-mi/MICmdCmdStack.h b/tools/lldb-mi/MICmdCmdStack.h
index bae43dceed6d..ebef7e197f5f 100644
--- a/tools/lldb-mi/MICmdCmdStack.h
+++ b/tools/lldb-mi/MICmdCmdStack.h
@@ -143,7 +143,10 @@ class CMICmdCmdStackListArguments : public CMICmdBase
bool m_bThreadInvalid; // True = yes invalid thread, false = thread object valid
CMICmnMIValueList m_miValueList;
const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
- const CMIUtilString m_constStrArgPrintValues; // Not handled by *this command
+ const CMIUtilString m_constStrArgPrintValues;
+ const CMIUtilString m_constStrArgNoValues;
+ const CMIUtilString m_constStrArgAllValues;
+ const CMIUtilString m_constStrArgSimpleValues;
};
//++ ============================================================================
@@ -179,5 +182,8 @@ class CMICmdCmdStackListLocals : public CMICmdBase
CMICmnMIValueList m_miValueList;
const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
const CMIUtilString m_constStrArgFrame; // Not specified in MI spec but Eclipse gives this option
- const CMIUtilString m_constStrArgPrintValues; // Not handled by *this command
+ const CMIUtilString m_constStrArgPrintValues;
+ const CMIUtilString m_constStrArgNoValues;
+ const CMIUtilString m_constStrArgAllValues;
+ const CMIUtilString m_constStrArgSimpleValues;
};
diff --git a/tools/lldb-mi/MICmdCmdTarget.cpp b/tools/lldb-mi/MICmdCmdTarget.cpp
index ec19493af33b..c3ef0b44e806 100644
--- a/tools/lldb-mi/MICmdCmdTarget.cpp
+++ b/tools/lldb-mi/MICmdCmdTarget.cpp
@@ -20,9 +20,9 @@
//--
// Third Party Headers:
-#include <lldb/API/SBStream.h>
-#include <lldb/API/SBCommandInterpreter.h>
-#include <lldb/API/SBCommandReturnObject.h>
+#include "lldb/API/SBStream.h"
+#include "lldb/API/SBCommandInterpreter.h"
+#include "lldb/API/SBCommandReturnObject.h"
// In-house headers:
#include "MICmdCmdTarget.h"
@@ -100,7 +100,7 @@ CMICmdCmdTargetSelect::Execute(void)
// Check we have a valid target
// Note: target created via 'file-exec-and-symbols' command
- if (!rSessionInfo.m_lldbTarget.IsValid())
+ if (!rSessionInfo.GetTarget().IsValid())
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT), m_cmdData.strMiCmd.c_str()));
return MIstatus::failure;
@@ -120,7 +120,7 @@ CMICmdCmdTargetSelect::Execute(void)
// Ask LLDB to collect to the target port
const MIchar *pPlugin("gdb-remote");
lldb::SBError error;
- lldb::SBProcess process = rSessionInfo.m_lldbTarget.ConnectRemote(rSessionInfo.m_rLlldbListener, strUrl.c_str(), pPlugin, error);
+ lldb::SBProcess process = rSessionInfo.GetTarget().ConnectRemote(rSessionInfo.GetListener(), strUrl.c_str(), pPlugin, error);
// Verify that we have managed to connect successfully
lldb::SBStream errMsg;
@@ -135,16 +135,11 @@ CMICmdCmdTargetSelect::Execute(void)
return MIstatus::failure;
}
- // Save the process in the session info
- // Note: Order is important here since this process handle may be used by CMICmnLLDBDebugHandleEvents
- // which can fire when interpreting via HandleCommand() below.
- rSessionInfo.m_lldbProcess = process;
-
// Set the environment path if we were given one
CMIUtilString strWkDir;
if (rSessionInfo.SharedDataRetrieve<CMIUtilString>(rSessionInfo.m_constStrSharedDataKeyWkDir, strWkDir))
{
- lldb::SBDebugger &rDbgr = rSessionInfo.m_rLldbDebugger;
+ lldb::SBDebugger &rDbgr = rSessionInfo.GetDebugger();
if (!rDbgr.SetCurrentPlatformSDKRoot(strWkDir.c_str()))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FNFAILED), m_cmdData.strMiCmd.c_str(), "target-select"));
@@ -156,7 +151,7 @@ CMICmdCmdTargetSelect::Execute(void)
CMIUtilString strSolibPath;
if (rSessionInfo.SharedDataRetrieve<CMIUtilString>(rSessionInfo.m_constStrSharedDataSolibPath, strSolibPath))
{
- lldb::SBDebugger &rDbgr = rSessionInfo.m_rLldbDebugger;
+ lldb::SBDebugger &rDbgr = rSessionInfo.GetDebugger();
lldb::SBCommandInterpreter cmdIterpreter = rDbgr.GetCommandInterpreter();
CMIUtilString strCmdString = CMIUtilString::Format("target modules search-paths add . %s", strSolibPath.c_str());
@@ -190,7 +185,7 @@ CMICmdCmdTargetSelect::Acknowledge(void)
m_miResultRecord = miRecordResult;
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::pid_t pid = rSessionInfo.m_lldbProcess.GetProcessID();
+ lldb::pid_t pid = rSessionInfo.GetProcess().GetProcessID();
// Prod the client i.e. Eclipse with out-of-band results to help it 'continue' because it is using LLDB debugger
// Give the client '=thread-group-started,id="i1"'
m_bHasResultRecordExtra = true;
diff --git a/tools/lldb-mi/MICmdCmdThread.cpp b/tools/lldb-mi/MICmdCmdThread.cpp
index 3a448a777008..52fd96050632 100644
--- a/tools/lldb-mi/MICmdCmdThread.cpp
+++ b/tools/lldb-mi/MICmdCmdThread.cpp
@@ -20,8 +20,8 @@
//--
// Third Party Headers:
-#include <lldb/API/SBBreakpointLocation.h>
-#include <lldb/API/SBThread.h>
+#include "lldb/API/SBBreakpointLocation.h"
+#include "lldb/API/SBThread.h"
// In-house headers:
#include "MICmdCmdThread.h"
@@ -99,12 +99,12 @@ CMICmdCmdThreadInfo::Execute(void)
}
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess &rProcess = rSessionInfo.m_lldbProcess;
- lldb::SBThread thread = rProcess.GetSelectedThread();
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
+ lldb::SBThread thread = sbProcess.GetSelectedThread();
if (m_bSingleThread)
{
- thread = rProcess.GetThreadByIndexID(nThreadId);
+ thread = sbProcess.GetThreadByIndexID(nThreadId);
m_bThreadInvalid = thread.IsValid();
if (!m_bThreadInvalid)
return MIstatus::success;
@@ -120,10 +120,10 @@ CMICmdCmdThreadInfo::Execute(void)
// Multiple threads
m_vecMIValueTuple.clear();
- const MIuint nThreads = rProcess.GetNumThreads();
+ const MIuint nThreads = sbProcess.GetNumThreads();
for (MIuint i = 0; i < nThreads; i++)
{
- lldb::SBThread thread = rProcess.GetThreadAtIndex(i);
+ lldb::SBThread thread = sbProcess.GetThreadAtIndex(i);
if (thread.IsValid())
{
CMICmnMIValueTuple miTuple;
diff --git a/tools/lldb-mi/MICmdCmdVar.cpp b/tools/lldb-mi/MICmdCmdVar.cpp
index 4aa4c2ae97cf..e9568beb173c 100644
--- a/tools/lldb-mi/MICmdCmdVar.cpp
+++ b/tools/lldb-mi/MICmdCmdVar.cpp
@@ -28,8 +28,8 @@
//--
// Third Party Headers:
-#include <lldb/API/SBStream.h>
-#include <lldb/API/SBThread.h>
+#include "lldb/API/SBStream.h"
+#include "lldb/API/SBThread.h"
// In-house headers:
#include "MICmdCmdVar.h"
@@ -129,16 +129,15 @@ CMICmdCmdVarCreate::Execute(void)
// Retrieve the --thread option's thread ID (only 1)
MIuint64 nThreadId = UINT64_MAX;
- if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
+ if (pArgThread->GetFound() && !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str()));
return MIstatus::failure;
}
- m_nThreadId = nThreadId;
// Retrieve the --frame option's number
MIuint64 nFrame = UINT64_MAX;
- if (!pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame))
+ if (pArgThread->GetFound() && !pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgFrame.c_str()));
return MIstatus::failure;
@@ -152,27 +151,41 @@ CMICmdCmdVarCreate::Execute(void)
nFrame = pOption->GetValue();
}
- bool bAutoName = false;
- const CMIUtilString strArgName;
+ m_strVarName = "<unnamedvariable>";
if (pArgName->GetFound())
{
const CMIUtilString &rArg = pArgName->GetValue();
- bAutoName = (rArg == "-");
+ const bool bAutoName = (rArg == "-");
+ if (bAutoName)
+ {
+ m_strVarName = CMIUtilString::Format("var%u", CMICmnLLDBDebugSessionInfoVarObj::VarObjIdGet());
+ CMICmnLLDBDebugSessionInfoVarObj::VarObjIdInc();
+ }
+ else
+ m_strVarName = rArg;
+ }
+
+ bool bCurrentFrame = false;
+ if (pArgFrameAddr->GetFound())
+ {
+ const CMIUtilString &rStrFrameAddr(pArgFrameAddr->GetValue());
+ bCurrentFrame = CMIUtilString::Compare(rStrFrameAddr, "*");
+ if (!bCurrentFrame && (nFrame == UINT64_MAX))
+ {
+ //FIXME: *addr isn't implemented. Exit with error if --thread isn't specified.
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgFrame.c_str()));
+ return MIstatus::failure;
+ }
}
const CMIUtilString &rStrExpression(pArgExpression->GetValue());
m_strExpression = rStrExpression;
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- m_strVarName = "<unnamedvariable>";
- if (bAutoName)
- {
- m_strVarName = CMIUtilString::Format("var%u", CMICmnLLDBDebugSessionInfoVarObj::VarObjIdGet());
- CMICmnLLDBDebugSessionInfoVarObj::VarObjIdInc();
- }
- lldb::SBProcess &rProcess = rSessionInfo.m_lldbProcess;
- lldb::SBThread thread = rProcess.GetThreadByIndexID(nThreadId);
- lldb::SBFrame frame = thread.GetFrameAtIndex(nFrame);
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
+ lldb::SBThread thread = (nThreadId != UINT64_MAX) ? sbProcess.GetThreadByIndexID(nThreadId) : sbProcess.GetSelectedThread();
+ m_nThreadId = thread.GetIndexID();
+ lldb::SBFrame frame = bCurrentFrame ? thread.GetSelectedFrame() : thread.GetFrameAtIndex(nFrame);
lldb::SBValue value = frame.FindVariable(rStrExpression.c_str());
if (!value.IsValid())
value = frame.EvaluateExpression(rStrExpression.c_str());
@@ -260,7 +273,8 @@ CMICmdCmdVarCreate::CreateSelf(void)
// Throws: None.
//--
CMICmdCmdVarUpdate::CMICmdCmdVarUpdate(void)
- : m_constStrArgPrintValues("print-values")
+ : m_eVarInfoFormat(CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues)
+ , m_constStrArgPrintValues("print-values")
, m_constStrArgName("name")
, m_bValueChangedArrayType(false)
, m_bValueChangedCompositeType(false)
@@ -297,7 +311,7 @@ CMICmdCmdVarUpdate::~CMICmdCmdVarUpdate(void)
bool
CMICmdCmdVarUpdate::ParseArgs(void)
{
- bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgPrintValues, false, false)));
+ bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgPrintValues, false, true)));
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgName, true, true)));
return (bOk && ParseValidateCmdOptions());
}
@@ -314,6 +328,7 @@ CMICmdCmdVarUpdate::ParseArgs(void)
bool
CMICmdCmdVarUpdate::Execute(void)
{
+ CMICMDBASE_GETOPTION(pArgPrintValues, Number, m_constStrArgPrintValues);
CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
const CMIUtilString &rVarObjName(pArgName->GetValue());
@@ -324,6 +339,14 @@ CMICmdCmdVarUpdate::Execute(void)
return MIstatus::failure;
}
+ const MIuint nPrintValues = pArgPrintValues->GetValue();
+ if (nPrintValues >= CMICmnLLDBDebugSessionInfo::kNumVariableInfoFormats)
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PRINT_VALUES), m_cmdData.strMiCmd.c_str()));
+ return MIstatus::failure;
+ }
+ m_eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(nPrintValues);
+
const CMIUtilString &rVarRealName(varObj.GetNameReal());
MIunused(rVarRealName);
lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
@@ -413,9 +436,12 @@ CMICmdCmdVarUpdate::Acknowledge(void)
const CMICmnMIValueConst miValueConst(m_strValueName);
CMICmnMIValueResult miValueResult("name", miValueConst);
CMICmnMIValueTuple miValueTuple(miValueResult);
- const CMICmnMIValueConst miValueConst2(strValue);
- CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
+ if (m_eVarInfoFormat != CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues)
+ {
+ const CMICmnMIValueConst miValueConst2(strValue);
+ CMICmnMIValueResult miValueResult2("value", miValueConst2);
+ miValueTuple.Add(miValueResult2);
+ }
const CMICmnMIValueConst miValueConst3(strInScope);
CMICmnMIValueResult miValueResult3("in_scope", miValueConst3);
miValueTuple.Add(miValueResult3);
@@ -519,8 +545,8 @@ CMICmdCmdVarUpdate::ExamineSBValueForChange(const CMICmnLLDBDebugSessionInfoVarO
vrwbChanged = false;
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess &rProcess = rSessionInfo.m_lldbProcess;
- lldb::SBThread thread = rProcess.GetSelectedThread();
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
+ lldb::SBThread thread = sbProcess.GetSelectedThread();
if (thread.GetNumFrames() == 0)
{
return MIstatus::success;
@@ -964,7 +990,10 @@ CMICmdCmdVarListChildren::CMICmdCmdVarListChildren(void)
, m_nChildren(0)
, m_constStrArgPrintValues("print-values")
, m_constStrArgName("name")
-{
+ , m_constStrArgNoValues("no-values")
+ , m_constStrArgAllValues("all-values")
+ , m_constStrArgSimpleValues("simple-values")
+ {
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-list-children";
@@ -996,7 +1025,10 @@ CMICmdCmdVarListChildren::~CMICmdCmdVarListChildren(void)
bool
CMICmdCmdVarListChildren::ParseArgs(void)
{
- bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgPrintValues, false, false)));
+ bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgPrintValues, false, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgNoValues, false, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgAllValues, false, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgSimpleValues, false, true)));
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgName, true, true)));
return (bOk && ParseValidateCmdOptions());
}
@@ -1014,6 +1046,24 @@ bool
CMICmdCmdVarListChildren::Execute(void)
{
CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
+ CMICMDBASE_GETOPTION(pArgPrintValue, Number, m_constStrArgPrintValues);
+ CMICMDBASE_GETOPTION(pArgNoValue, OptionLong, m_constStrArgNoValues);
+ CMICMDBASE_GETOPTION(pArgAllValue, OptionLong, m_constStrArgAllValues);
+ CMICMDBASE_GETOPTION(pArgSimpleValue, OptionLong, m_constStrArgSimpleValues);
+
+ MIuint print_value = 0;
+ if (pArgPrintValue->GetFound())
+ {
+ MIuint tmp = pArgPrintValue->GetValue();
+ if (tmp <= 2)
+ print_value = tmp;
+ }
+ else if (pArgNoValue->GetFound())
+ print_value = 0; // no value
+ else if (pArgAllValue->GetFound())
+ print_value = 1; // all values
+ else if (pArgSimpleValue->GetFound())
+ print_value = 2; // simple values
const CMIUtilString &rVarObjName(pArgName->GetValue());
CMICmnLLDBDebugSessionInfoVarObj varObj;
@@ -1041,9 +1091,6 @@ CMICmdCmdVarListChildren::Execute(void)
const MIuint nChildren = member.GetNumChildren();
const CMIUtilString strThreadId(CMIUtilString::Format("%u", member.GetThread().GetIndexID()));
- // Varobj gets added to CMICmnLLDBDebugSessionInfoVarObj static container of varObjs
- CMICmnLLDBDebugSessionInfoVarObj var(strExp, name, member, rVarObjName);
-
// MI print "child={name=\"%s\",exp=\"%s\",numchild=\"%d\",value=\"%s\",type=\"%s\",thread-id=\"%u\",has_more=\"%u\"}"
const CMICmnMIValueConst miValueConst(name);
const CMICmnMIValueResult miValueResult("name", miValueConst);
@@ -1061,11 +1108,23 @@ CMICmdCmdVarListChildren::Execute(void)
const CMICmnMIValueConst miValueConst6(strThreadId);
const CMICmnMIValueResult miValueResult6("thread-id", miValueConst6);
miValueTuple.Add(miValueResult6);
- const CMICmnMIValueConst miValueConst7("0");
- const CMICmnMIValueResult miValueResult7("has_more", miValueConst7);
- miValueTuple.Add(miValueResult7);
- const CMICmnMIValueResult miValueResult8("child", miValueTuple);
- m_vecMiValueResult.push_back(miValueResult8);
+ // nChildren == 0 is used to check for simple values
+ if ( (print_value == 2 && nChildren == 0) || (print_value == 1) )
+ {
+ // Varobj gets added to CMICmnLLDBDebugSessionInfoVarObj static container of varObjs
+ CMICmnLLDBDebugSessionInfoVarObj var(strExp, name, member, rVarObjName);
+ const CMIUtilString strValue(
+ CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural));
+ const CMICmnMIValueConst miValueConst7(strValue);
+ const CMICmnMIValueResult miValueResult7("value", miValueConst7);
+ miValueTuple.Add(miValueResult7);
+ }
+ const CMICmnMIValueConst miValueConst8("0");
+ const CMICmnMIValueResult miValueResult8("has_more", miValueConst8);
+ miValueTuple.Add(miValueResult8);
+ const CMICmnMIValueResult miValueResult9("child", miValueTuple);
+ m_vecMiValueResult.push_back(miValueResult9);
+
}
return MIstatus::success;
@@ -1493,7 +1552,7 @@ CMICmdCmdVarShowAttributes::Execute(void)
const CMIUtilString &rVarObjName(pArgName->GetValue());
CMICmnLLDBDebugSessionInfoVarObj varObj;
- if (CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj))
+ if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str()));
return MIstatus::failure;
diff --git a/tools/lldb-mi/MICmdCmdVar.h b/tools/lldb-mi/MICmdCmdVar.h
index 34ce9e15af6c..add2058c029b 100644
--- a/tools/lldb-mi/MICmdCmdVar.h
+++ b/tools/lldb-mi/MICmdCmdVar.h
@@ -42,6 +42,7 @@
#include "MICmdBase.h"
#include "MICmnMIValueTuple.h"
#include "MICmnMIValueList.h"
+#include "MICmnLLDBDebugSessionInfo.h"
#include "MICmnLLDBDebugSessionInfoVarObj.h"
// Declarations:
@@ -129,6 +130,7 @@ class CMICmdCmdVarUpdate : public CMICmdBase
// Attribute:
private:
CMIUtilString m_strValueName;
+ CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e m_eVarInfoFormat;
const CMIUtilString m_constStrArgPrintValues; // Not handled by *this command
const CMIUtilString m_constStrArgName;
bool m_bValueChangedArrayType; // True = yes value changed, false = no change
@@ -274,8 +276,11 @@ class CMICmdCmdVarListChildren : public CMICmdBase
bool m_bValueValid; // True = yes SBValue object is valid, false = not valid
VecMIValueResult_t m_vecMiValueResult;
MIuint m_nChildren;
- const CMIUtilString m_constStrArgPrintValues; // Not handled by *this command
+ const CMIUtilString m_constStrArgPrintValues;
const CMIUtilString m_constStrArgName;
+ const CMIUtilString m_constStrArgNoValues;
+ const CMIUtilString m_constStrArgAllValues;
+ const CMIUtilString m_constStrArgSimpleValues;
};
//++ ============================================================================
diff --git a/tools/lldb-mi/MICmnLLDBBroadcaster.h b/tools/lldb-mi/MICmnLLDBBroadcaster.h
index 70d092589412..62ca0542dbf1 100644
--- a/tools/lldb-mi/MICmnLLDBBroadcaster.h
+++ b/tools/lldb-mi/MICmnLLDBBroadcaster.h
@@ -22,7 +22,7 @@
#pragma once
// In-house headers:
-#include <lldb/API/SBBroadcaster.h>
+#include "lldb/API/SBBroadcaster.h"
#include "MICmnBase.h"
#include "MIUtilSingletonBase.h"
diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
index 3e9ed226182f..7f6d9d53811a 100644
--- a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
+++ b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
@@ -20,13 +20,13 @@
//--
// Third party headers:
-#include <lldb/API/SBThread.h>
+#include "lldb/API/SBThread.h"
#ifdef _WIN32
#include <io.h> // For the ::_access()
#else
#include <unistd.h> // For the ::access()
#endif // _WIN32
-#include <lldb/API/SBBreakpointLocation.h>
+#include "lldb/API/SBBreakpointLocation.h"
// In-house headers:
#include "MICmnLLDBDebugSessionInfo.h"
@@ -47,9 +47,7 @@
// Throws: None.
//--
CMICmnLLDBDebugSessionInfo::CMICmnLLDBDebugSessionInfo(void)
- : m_rLldbDebugger(CMICmnLLDBDebugger::Instance().GetTheDebugger())
- , m_rLlldbListener(CMICmnLLDBDebugger::Instance().GetTheListener())
- , m_nBrkPointCntMax(INT32_MAX)
+ : m_nBrkPointCntMax(INT32_MAX)
, m_currentSelectedThread(LLDB_INVALID_THREAD_ID)
, m_constStrSharedDataKeyWkDir("Working Directory")
, m_constStrSharedDataSolibPath("Solib Path")
@@ -226,7 +224,7 @@ CMICmnLLDBDebugSessionInfo::RecordBrkPtInfoDelete(const MIuint vnBrkPtId)
bool
CMICmnLLDBDebugSessionInfo::GetThreadFrames(const SMICmdData &vCmdData, const MIuint vThreadIdx, CMIUtilString &vwrThreadFrames)
{
- lldb::SBThread thread = m_lldbProcess.GetThreadByIndexID(vThreadIdx);
+ lldb::SBThread thread = GetProcess().GetThreadByIndexID(vThreadIdx);
const uint32_t nFrames = thread.GetNumFrames();
if (nFrames == 0)
{
@@ -255,7 +253,7 @@ CMICmnLLDBDebugSessionInfo::GetThreadFrames(const SMICmdData &vCmdData, const MI
// Function args
CMICmnMIValueList miValueList(true);
const MIuint maskVarTypes = eVariableType_Arguments;
- if (!MIResponseFormVariableInfo(frame, maskVarTypes, miValueList))
+ if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList))
return MIstatus::failure;
const MIchar *pUnknown = "??";
@@ -299,7 +297,7 @@ CMICmnLLDBDebugSessionInfo::GetThreadFrames(const SMICmdData &vCmdData, const MI
bool
CMICmnLLDBDebugSessionInfo::GetThreadFrames2(const SMICmdData &vCmdData, const MIuint vThreadIdx, CMIUtilString &vwrThreadFrames)
{
- lldb::SBThread thread = m_lldbProcess.GetThreadByIndexID(vThreadIdx);
+ lldb::SBThread thread = GetProcess().GetThreadByIndexID(vThreadIdx);
const uint32_t nFrames = thread.GetNumFrames();
if (nFrames == 0)
{
@@ -328,7 +326,7 @@ CMICmnLLDBDebugSessionInfo::GetThreadFrames2(const SMICmdData &vCmdData, const M
// Function args
CMICmnMIValueList miValueList(true);
const MIuint maskVarTypes = eVariableType_Arguments;
- if (!MIResponseFormVariableInfo2(frame, maskVarTypes, miValueList))
+ if (!MIResponseFormVariableInfo2(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList))
return MIstatus::failure;
const MIchar *pUnknown = "??";
@@ -648,6 +646,7 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo2(const SMICmdData &vCmdData
// Type: Method.
// Args: vrFrame - (R) LLDB thread object.
// vMaskVarTypes - (R) Construed according to VariableType_e.
+// veVarInfoFormat - (R) The type of variable info that should be shown.
// vwrMIValueList - (W) MI value list object.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
@@ -655,7 +654,7 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo2(const SMICmdData &vCmdData
//--
bool
CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo2(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes,
- CMICmnMIValueList &vwrMiValueList)
+ const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList)
{
bool bOk = MIstatus::success;
lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame);
@@ -688,6 +687,7 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo2(const lldb::SBFrame &vrF
// Type: Method.
// Args: vrFrame - (R) LLDB thread object.
// vMaskVarTypes - (R) Construed according to VariableType_e.
+// veVarInfoFormat - (R) The type of variable info that should be shown.
// vwrMIValueList - (W) MI value list object.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
@@ -695,7 +695,7 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo2(const lldb::SBFrame &vrF
//--
bool
CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes,
- CMICmnMIValueList &vwrMiValueList)
+ const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList)
{
bool bOk = MIstatus::success;
lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame);
@@ -711,7 +711,7 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo(const lldb::SBFrame &vrFr
for (MIuint i = 0; bOk && (i < nArgs); i++)
{
lldb::SBValue value = listArg.GetValueAtIndex(i);
- bOk = GetVariableInfo(nMaxRecusiveDepth, value, false, vwrMiValueList, nCurrentRecursiveDepth);
+ bOk = GetVariableInfo(nMaxRecusiveDepth, value, false, veVarInfoFormat, vwrMiValueList, nCurrentRecursiveDepth);
}
return bOk;
@@ -725,6 +725,7 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo(const lldb::SBFrame &vrFr
// Type: Method.
// Args: vrFrame - (R) LLDB thread object.
// vMaskVarTypes - (R) Construed according to VariableType_e.
+// veVarInfoFormat - (R) The type of variable info that should be shown.
// vwrMIValueList - (W) MI value list object.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
@@ -732,7 +733,7 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo(const lldb::SBFrame &vrFr
//--
bool
CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo3(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes,
- CMICmnMIValueList &vwrMiValueList)
+ const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList)
{
bool bOk = MIstatus::success;
lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame);
@@ -748,7 +749,7 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo3(const lldb::SBFrame &vrF
for (MIuint i = 0; bOk && (i < nArgs); i++)
{
lldb::SBValue value = listArg.GetValueAtIndex(i);
- bOk = GetVariableInfo2(nMaxRecusiveDepth, value, false, vwrMiValueList, nCurrentRecursiveDepth);
+ bOk = GetVariableInfo2(nMaxRecusiveDepth, value, false, veVarInfoFormat, vwrMiValueList, nCurrentRecursiveDepth);
}
return bOk;
@@ -763,15 +764,17 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo3(const lldb::SBFrame &vrF
// vrValue - (R) LLDB value object.
// vbIsChildValue - (R) True = Value object is a child of a higher Value object,
// - False = Value object not a child.
+// veVarInfoFormat - (R) The type of variable info that should be shown.
// vwrMIValueList - (W) MI value list object.
// vnDepth - (RW) The current recursive depth of this function.
-// // Return: MIstatus::success - Functional succeeded.
+// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool
CMICmnLLDBDebugSessionInfo::GetVariableInfo(const MIuint vnMaxDepth, const lldb::SBValue &vrValue, const bool vbIsChildValue,
- CMICmnMIValueList &vwrMiValueList, MIuint &vrwnDepth)
+ const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList,
+ MIuint &vrwnDepth)
{
// *** Update GetVariableInfo2() with any code changes here ***
@@ -809,46 +812,78 @@ CMICmnLLDBDebugSessionInfo::GetVariableInfo(const MIuint vnMaxDepth, const lldb:
else
{
// Basic types
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- miValueTuple.Add(miValueResult);
- const CMICmnMIValueConst miValueConst2(utilValue.GetValue());
- const CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
+ switch (veVarInfoFormat)
+ {
+ case eVariableInfoFormat_NoValues:
+ {
+ const CMICmnMIValueConst miValueConst(utilValue.GetName());
+ const CMICmnMIValueResult miValueResult("name", miValueConst);
+ return vwrMiValueList.Add(miValueResult);
+ }
+ case eVariableInfoFormat_AllValues:
+ case eVariableInfoFormat_SimpleValues:
+ {
+ const CMICmnMIValueConst miValueConst(utilValue.GetName());
+ const CMICmnMIValueResult miValueResult("name", miValueConst);
+ miValueTuple.Add(miValueResult);
+ const CMICmnMIValueConst miValueConst2(utilValue.GetValue());
+ const CMICmnMIValueResult miValueResult2("value", miValueConst2);
+ miValueTuple.Add(miValueResult2);
+ break;
+ }
+ default:
+ break;
+ }
return vwrMiValueList.Add(miValueTuple);
}
}
else if (bIsPointerType && utilValue.IsChildCharType())
{
- // Append string text to the parent value information
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- miValueTuple.Add(miValueResult);
-
- const CMIUtilString &rText(utilValue.GetChildValueCString());
- if (rText.empty())
- {
- const CMICmnMIValueConst miValueConst(utilValue.GetValue());
- const CMICmnMIValueResult miValueResult("value", miValueConst);
- miValueTuple.Add(miValueResult);
- }
- else
+ switch (veVarInfoFormat)
{
- if (utilValue.IsValueUnknown())
+ case eVariableInfoFormat_NoValues:
{
- const CMICmnMIValueConst miValueConst(rText);
- const CMICmnMIValueResult miValueResult("value", miValueConst);
- miValueTuple.Add(miValueResult);
+ const CMICmnMIValueConst miValueConst(utilValue.GetName());
+ const CMICmnMIValueResult miValueResult("name", miValueConst);
+ return vwrMiValueList.Add(miValueResult);
}
- else
+ case eVariableInfoFormat_AllValues:
+ case eVariableInfoFormat_SimpleValues:
{
- // Note code that has const in will not show the text suffix to the string pointer
- // i.e. const char * pMyStr = "blah"; ==> "0x00007000"" <-- Eclipse shows this
- // but char * pMyStr = "blah"; ==> "0x00007000" "blah"" <-- Eclipse shows this
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%s %s", utilValue.GetValue().c_str(), rText.c_str()));
- const CMICmnMIValueResult miValueResult("value", miValueConst);
+ // Append string text to the parent value information
+ const CMICmnMIValueConst miValueConst(utilValue.GetName());
+ const CMICmnMIValueResult miValueResult("name", miValueConst);
miValueTuple.Add(miValueResult);
+
+ const CMIUtilString &rText(utilValue.GetChildValueCString());
+ if (rText.empty())
+ {
+ const CMICmnMIValueConst miValueConst(utilValue.GetValue());
+ const CMICmnMIValueResult miValueResult("value", miValueConst);
+ miValueTuple.Add(miValueResult);
+ }
+ else
+ {
+ if (utilValue.IsValueUnknown())
+ {
+ const CMICmnMIValueConst miValueConst(rText);
+ const CMICmnMIValueResult miValueResult("value", miValueConst);
+ miValueTuple.Add(miValueResult);
+ }
+ else
+ {
+ // Note code that has const in will not show the text suffix to the string pointer
+ // i.e. const char * pMyStr = "blah"; ==> "0x00007000"" <-- Eclipse shows this
+ // but char * pMyStr = "blah"; ==> "0x00007000" "blah"" <-- Eclipse shows this
+ const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%s %s", utilValue.GetValue().c_str(), rText.c_str()));
+ const CMICmnMIValueResult miValueResult("value", miValueConst);
+ miValueTuple.Add(miValueResult);
+ }
+ }
+ break;
}
+ default:
+ break;
}
return vwrMiValueList.Add(miValueTuple);
}
@@ -865,30 +900,62 @@ CMICmnLLDBDebugSessionInfo::GetVariableInfo(const MIuint vnMaxDepth, const lldb:
else
{
// Basic types
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- miValueTuple.Add(miValueResult);
- const CMICmnMIValueConst miValueConst2(utilValue.GetValue());
- const CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
+ switch (veVarInfoFormat)
+ {
+ case eVariableInfoFormat_NoValues:
+ {
+ const CMICmnMIValueConst miValueConst(utilValue.GetName());
+ const CMICmnMIValueResult miValueResult("name", miValueConst);
+ return vwrMiValueList.Add(miValueResult);
+ }
+ case eVariableInfoFormat_AllValues:
+ case eVariableInfoFormat_SimpleValues:
+ {
+ const CMICmnMIValueConst miValueConst(utilValue.GetName());
+ const CMICmnMIValueResult miValueResult("name", miValueConst);
+ miValueTuple.Add(miValueResult);
+ const CMICmnMIValueConst miValueConst2(utilValue.GetValue());
+ const CMICmnMIValueResult miValueResult2("value", miValueConst2);
+ miValueTuple.Add(miValueResult2);
+ break;
+ }
+ default:
+ break;
+ }
return vwrMiValueList.Add(miValueTuple);
}
}
else
{
- // Build parent child composite types
- CMICmnMIValueList miValueList(true);
- for (MIuint i = 0; bOk && (i < nChildren); i++)
+ switch (veVarInfoFormat)
{
- lldb::SBValue member = rValue.GetChildAtIndex(i);
- bOk = GetVariableInfo(vnMaxDepth, member, true, miValueList, ++vrwnDepth);
+ case eVariableInfoFormat_NoValues:
+ {
+ const CMICmnMIValueConst miValueConst(utilValue.GetName());
+ const CMICmnMIValueResult miValueResult("name", miValueConst);
+ return vwrMiValueList.Add(miValueResult);
+ }
+ case eVariableInfoFormat_AllValues:
+ case eVariableInfoFormat_SimpleValues:
+ {
+ // Build parent child composite types
+ CMICmnMIValueList miValueList(true);
+ for (MIuint i = 0; bOk && (i < nChildren); i++)
+ {
+ lldb::SBValue member = rValue.GetChildAtIndex(i);
+ bOk = GetVariableInfo(vnMaxDepth, member, true, veVarInfoFormat, miValueList, ++vrwnDepth);
+ }
+ const CMICmnMIValueConst miValueConst(utilValue.GetName());
+ const CMICmnMIValueResult miValueResult("name", miValueConst);
+ miValueTuple.Add(miValueResult);
+ const CMICmnMIValueConst miValueConst2(CMIUtilString::Format("{%s}", miValueList.ExtractContentNoBrackets().c_str()));
+ const CMICmnMIValueResult miValueResult2("value", miValueConst2);
+ miValueTuple.Add(miValueResult2);
+ break;
+ }
+ default:
+ break;
}
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- miValueTuple.Add(miValueResult);
- const CMICmnMIValueConst miValueConst2(CMIUtilString::Format("{%s}", miValueList.ExtractContentNoBrackets().c_str()));
- const CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
return vwrMiValueList.Add(miValueTuple);
}
}
@@ -902,6 +969,7 @@ CMICmnLLDBDebugSessionInfo::GetVariableInfo(const MIuint vnMaxDepth, const lldb:
// vrValue - (R) LLDB value object.
// vbIsChildValue - (R) True = Value object is a child of a higher Value object,
// - False = Value object not a child.
+// veVarInfoFormat - (R) The type of variable info that should be shown.
// vwrMIValueList - (W) MI value list object.
// vnDepth - (RW) The current recursive depth of this function.
// // Return: MIstatus::success - Functional succeeded.
@@ -910,7 +978,8 @@ CMICmnLLDBDebugSessionInfo::GetVariableInfo(const MIuint vnMaxDepth, const lldb:
//--
bool
CMICmnLLDBDebugSessionInfo::GetVariableInfo2(const MIuint vnMaxDepth, const lldb::SBValue &vrValue, const bool vbIsChildValue,
- CMICmnMIValueList &vwrMiValueList, MIuint &vrwnDepth)
+ const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList,
+ MIuint &vrwnDepth)
{
// *** Update GetVariableInfo() with any code changes here ***
@@ -937,64 +1006,112 @@ CMICmnLLDBDebugSessionInfo::GetVariableInfo2(const MIuint vnMaxDepth, const lldb
else
{
// Basic types
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- miValueTuple.Add(miValueResult);
- const CMICmnMIValueConst miValueConst2(utilValue.GetValue());
- const CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
+ switch (veVarInfoFormat)
+ {
+ case eVariableInfoFormat_NoValues:
+ {
+ const CMICmnMIValueConst miValueConst(utilValue.GetName());
+ const CMICmnMIValueResult miValueResult("name", miValueConst);
+ return vwrMiValueList.Add(miValueResult);
+ }
+ case eVariableInfoFormat_AllValues:
+ case eVariableInfoFormat_SimpleValues:
+ {
+ const CMICmnMIValueConst miValueConst(utilValue.GetName());
+ const CMICmnMIValueResult miValueResult("name", miValueConst);
+ miValueTuple.Add(miValueResult);
+ const CMICmnMIValueConst miValueConst2(utilValue.GetValue());
+ const CMICmnMIValueResult miValueResult2("value", miValueConst2);
+ miValueTuple.Add(miValueResult2);
+ break;
+ }
+ default:
+ break;
+ }
return vwrMiValueList.Add(miValueTuple);
}
}
else if (utilValue.IsChildCharType())
{
- // Append string text to the parent value information
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- miValueTuple.Add(miValueResult);
-
- const CMIUtilString &rText(utilValue.GetChildValueCString());
- if (rText.empty())
- {
- const CMICmnMIValueConst miValueConst(utilValue.GetValue());
- const CMICmnMIValueResult miValueResult("value", miValueConst);
- miValueTuple.Add(miValueResult);
- }
- else
+ switch (veVarInfoFormat)
{
- if (utilValue.IsValueUnknown())
+ case eVariableInfoFormat_NoValues:
{
- const CMICmnMIValueConst miValueConst(rText);
- const CMICmnMIValueResult miValueResult("value", miValueConst);
- miValueTuple.Add(miValueResult);
+ const CMICmnMIValueConst miValueConst(utilValue.GetName());
+ const CMICmnMIValueResult miValueResult("name", miValueConst);
+ return vwrMiValueList.Add(miValueResult);
}
- else
+ case eVariableInfoFormat_AllValues:
+ case eVariableInfoFormat_SimpleValues:
{
- // Note code that has const in will not show the text suffix to the string pointer
- // i.e. const char * pMyStr = "blah"; ==> "0x00007000"" <-- Eclipse shows this
- // but char * pMyStr = "blah"; ==> "0x00007000" "blah"" <-- Eclipse shows this
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%s %s", utilValue.GetValue().c_str(), rText.c_str()));
- const CMICmnMIValueResult miValueResult("value", miValueConst);
+ // Append string text to the parent value information
+ const CMICmnMIValueConst miValueConst(utilValue.GetName());
+ const CMICmnMIValueResult miValueResult("name", miValueConst);
miValueTuple.Add(miValueResult);
+
+ const CMIUtilString &rText(utilValue.GetChildValueCString());
+ if (rText.empty())
+ {
+ const CMICmnMIValueConst miValueConst(utilValue.GetValue());
+ const CMICmnMIValueResult miValueResult("value", miValueConst);
+ miValueTuple.Add(miValueResult);
+ }
+ else
+ {
+ if (utilValue.IsValueUnknown())
+ {
+ const CMICmnMIValueConst miValueConst(rText);
+ const CMICmnMIValueResult miValueResult("value", miValueConst);
+ miValueTuple.Add(miValueResult);
+ }
+ else
+ {
+ // Note code that has const in will not show the text suffix to the string pointer
+ // i.e. const char * pMyStr = "blah"; ==> "0x00007000"" <-- Eclipse shows this
+ // but char * pMyStr = "blah"; ==> "0x00007000" "blah"" <-- Eclipse shows this
+ const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%s %s", utilValue.GetValue().c_str(), rText.c_str()));
+ const CMICmnMIValueResult miValueResult("value", miValueConst);
+ miValueTuple.Add(miValueResult);
+ }
+ }
+ break;
}
+ default:
+ break;
}
return vwrMiValueList.Add(miValueTuple);
}
else
{
- // Build parent child composite types
- CMICmnMIValueList miValueList(true);
- for (MIuint i = 0; bOk && (i < nChildren); i++)
+ switch (veVarInfoFormat)
{
- lldb::SBValue member = rValue.GetChildAtIndex(i);
- bOk = GetVariableInfo(vnMaxDepth, member, true, miValueList, ++vrwnDepth);
+ case eVariableInfoFormat_NoValues:
+ {
+ const CMICmnMIValueConst miValueConst(utilValue.GetName());
+ const CMICmnMIValueResult miValueResult("name", miValueConst);
+ return vwrMiValueList.Add(miValueResult);
+ }
+ case eVariableInfoFormat_AllValues:
+ case eVariableInfoFormat_SimpleValues:
+ {
+ // Build parent child composite types
+ CMICmnMIValueList miValueList(true);
+ for (MIuint i = 0; bOk && (i < nChildren); i++)
+ {
+ lldb::SBValue member = rValue.GetChildAtIndex(i);
+ bOk = GetVariableInfo(vnMaxDepth, member, true, veVarInfoFormat, miValueList, ++vrwnDepth);
+ }
+ const CMICmnMIValueConst miValueConst(utilValue.GetName());
+ const CMICmnMIValueResult miValueResult("name", miValueConst);
+ miValueTuple.Add(miValueResult);
+ const CMICmnMIValueConst miValueConst2(CMIUtilString::Format("{%s}", miValueList.ExtractContentNoBrackets().c_str()));
+ const CMICmnMIValueResult miValueResult2("value", miValueConst2);
+ miValueTuple.Add(miValueResult2);
+ break;
+ }
+ default:
+ break;
}
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- miValueTuple.Add(miValueResult);
- const CMICmnMIValueConst miValueConst2(CMIUtilString::Format("{%s}", miValueList.ExtractContentNoBrackets().c_str()));
- const CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
return vwrMiValueList.Add(miValueTuple);
}
}
@@ -1329,7 +1446,7 @@ CMICmnLLDBDebugSessionInfo::GetBrkPtInfo(const lldb::SBBreakpoint &vBrkPt, SBrkP
const MIchar *pFn = pUnkwn;
const MIchar *pFilePath = pUnkwn;
size_t nLine = 0;
- const size_t nAddr = brkPtAddr.GetLoadAddress(m_lldbTarget);
+ const size_t nAddr = brkPtAddr.GetLoadAddress(GetTarget());
lldb::SBCompileUnit rCmplUnit = symbolCntxt.GetCompileUnit();
if (rCmplUnit.IsValid())
@@ -1356,3 +1473,55 @@ CMICmnLLDBDebugSessionInfo::GetBrkPtInfo(const lldb::SBBreakpoint &vBrkPt, SBrkP
return MIstatus::success;
}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Get current debugger.
+// Type: Method.
+// Args: None.
+// Return: lldb::SBDebugger - current debugger.
+// Throws: None.
+//--
+lldb::SBDebugger &
+CMICmnLLDBDebugSessionInfo::GetDebugger() const
+{
+ return CMICmnLLDBDebugger::Instance().GetTheDebugger();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Get current listener.
+// Type: Method.
+// Args: None.
+// Return: lldb::SBListener - current listener.
+// Throws: None.
+//--
+lldb::SBListener &
+CMICmnLLDBDebugSessionInfo::GetListener() const
+{
+ return CMICmnLLDBDebugger::Instance().GetTheListener();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Get current target.
+// Type: Method.
+// Args: None.
+// Return: lldb::SBTarget - current target.
+// Throws: None.
+//--
+lldb::SBTarget
+CMICmnLLDBDebugSessionInfo::GetTarget() const
+{
+ return GetDebugger().GetSelectedTarget();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Get current process.
+// Type: Method.
+// Args: None.
+// Return: lldb::SBProcess - current process.
+// Throws: None.
+//--
+lldb::SBProcess
+CMICmnLLDBDebugSessionInfo::GetProcess() const
+{
+ return GetTarget().GetProcess();
+}
diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h
index e2463f1c89ca..2e592f1f43c6 100644
--- a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h
+++ b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h
@@ -24,10 +24,10 @@
// Third party headers:
#include <map>
#include <vector>
-#include <lldb/API/SBDebugger.h>
-#include <lldb/API/SBListener.h>
-#include <lldb/API/SBProcess.h>
-#include <lldb/API/SBTarget.h>
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBListener.h"
+#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBTarget.h"
// In-house headers:
#include "MICmnBase.h"
@@ -35,6 +35,7 @@
#include "MICmnLLDBDebugSessionInfoVarObj.h"
#include "MICmnMIValueTuple.h"
#include "MIUtilMapIdToVariant.h"
+#include "MIUtilThreadBaseStd.h"
// Declarations:
class CMICmnLLDBDebugger;
@@ -116,6 +117,17 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton<CMIC
eVariableType_Arguments = (1u << 3) // Arguments.
};
+ //++ ===================================================================
+ // Details: Determine the information that should be shown by using MIResponseFormVariableInfo family functions.
+ //--
+ enum VariableInfoFormat_e
+ {
+ eVariableInfoFormat_NoValues,
+ eVariableInfoFormat_AllValues,
+ eVariableInfoFormat_SimpleValues,
+ kNumVariableInfoFormats
+ };
+
// Typedefs:
public:
typedef std::vector<uint32_t> VecActiveThreadId_t;
@@ -147,23 +159,27 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton<CMIC
bool MIResponseFormThreadInfo(const SMICmdData &vCmdData, const lldb::SBThread &vrThread, CMICmnMIValueTuple &vwrMIValueTuple);
bool MIResponseFormThreadInfo2(const SMICmdData &vCmdData, const lldb::SBThread &vrThread, CMICmnMIValueTuple &vwrMIValueTuple);
bool MIResponseFormThreadInfo3(const SMICmdData &vCmdData, const lldb::SBThread &vrThread, CMICmnMIValueTuple &vwrMIValueTuple);
- bool MIResponseFormVariableInfo(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes, CMICmnMIValueList &vwrMiValueList);
- bool MIResponseFormVariableInfo2(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes, CMICmnMIValueList &vwrMiValueList);
- bool MIResponseFormVariableInfo3(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes, CMICmnMIValueList &vwrMiValueList);
+ bool MIResponseFormVariableInfo(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes,
+ const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList);
+ bool MIResponseFormVariableInfo2(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes,
+ const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList);
+ bool MIResponseFormVariableInfo3(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes,
+ const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList);
bool MIResponseFormBrkPtFrameInfo(const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple);
bool MIResponseFormBrkPtInfo(const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple);
bool GetBrkPtInfo(const lldb::SBBreakpoint &vBrkPt, SBrkPtInfo &vrwBrkPtInfo) const;
bool RecordBrkPtInfo(const MIuint vnBrkPtId, const SBrkPtInfo &vrBrkPtInfo);
bool RecordBrkPtInfoGet(const MIuint vnBrkPtId, SBrkPtInfo &vrwBrkPtInfo) const;
bool RecordBrkPtInfoDelete(const MIuint vnBrkPtId);
+ CMIUtilThreadMutex& GetSessionMutex() { return m_sessionMutex;}
+ lldb::SBDebugger &GetDebugger() const;
+ lldb::SBListener &GetListener() const;
+ lldb::SBTarget GetTarget() const;
+ lldb::SBProcess GetProcess() const;
// Attributes:
public:
// The following are available to all command instances
- lldb::SBDebugger &m_rLldbDebugger;
- lldb::SBListener &m_rLlldbListener;
- lldb::SBTarget m_lldbTarget;
- lldb::SBProcess m_lldbProcess;
const MIuint m_nBrkPointCntMax;
VecActiveThreadId_t m_vecActiveThreadId;
lldb::tid_t m_currentSelectedThread;
@@ -186,9 +202,9 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton<CMIC
void operator=(const CMICmnLLDBDebugSessionInfo &);
//
bool GetVariableInfo(const MIuint vnMaxDepth, const lldb::SBValue &vrValue, const bool vbIsChildValue,
- CMICmnMIValueList &vwrMiValueList, MIuint &vrwnDepth);
+ const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList, MIuint &vrwnDepth);
bool GetVariableInfo2(const MIuint vnMaxDepth, const lldb::SBValue &vrValue, const bool vbIsChildValue,
- CMICmnMIValueList &vwrMiValueList, MIuint &vrwnDepth);
+ const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList, MIuint &vrwnDepth);
// Overridden:
private:
@@ -200,6 +216,7 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton<CMIC
CMIUtilMapIdToVariant m_mapIdToSessionData; // Hold and retrieve key to value data available across all commands
VecVarObj_t m_vecVarObj; // Vector of session variable objects
MapBrkPtIdToBrkPtInfo_t m_mapBrkPtIdToBrkPtInfo;
+ CMIUtilThreadMutex m_sessionMutex;
};
//++ ------------------------------------------------------------------------------------
diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h b/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h
index 94f62a42aa6a..ecc960c85d0a 100644
--- a/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h
+++ b/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h
@@ -23,7 +23,7 @@
// Third Party Headers:
#include <map>
-#include <lldb/API/SBValue.h>
+#include "lldb/API/SBValue.h"
// In-house headers:
#include "MIUtilString.h"
diff --git a/tools/lldb-mi/MICmnLLDBDebugger.cpp b/tools/lldb-mi/MICmnLLDBDebugger.cpp
index 273b805156f4..37ddda4db0ce 100644
--- a/tools/lldb-mi/MICmnLLDBDebugger.cpp
+++ b/tools/lldb-mi/MICmnLLDBDebugger.cpp
@@ -20,10 +20,10 @@
//--
// Third party headers:
-#include <lldb/API/SBTarget.h>
-#include <lldb/API/SBThread.h>
-#include <lldb/API/SBProcess.h>
-#include <lldb/API/SBCommandInterpreter.h>
+#include "lldb/API/SBTarget.h"
+#include "lldb/API/SBThread.h"
+#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBCommandInterpreter.h"
// In-house headers:
#include "MICmnLLDBDebugger.h"
@@ -148,7 +148,8 @@ CMICmnLLDBDebugger::Shutdown(void)
// Explicitly delete the remote target in case MI needs to exit prematurely otherwise
// LLDB debugger may hang in its Destroy() fn waiting on events
- m_lldbDebugger.DeleteTarget(CMICmnLLDBDebugSessionInfo::Instance().m_lldbTarget);
+ lldb::SBTarget sbTarget = CMICmnLLDBDebugSessionInfo::Instance().GetTarget();
+ m_lldbDebugger.DeleteTarget(sbTarget);
// Debug: May need this but does seem to work without it so commented out the fudge 19/06/2014
// It appears we need to wait as hang does not occur when hitting a debug breakpoint here
@@ -663,7 +664,13 @@ CMICmnLLDBDebugger::MonitorSBListenerEvents(bool &vrbIsAlive)
bool bHandledEvent = false;
bool bExitAppEvent = false;
- const bool bOk = CMICmnLLDBDebuggerHandleEvents::Instance().HandleEvent(event, bHandledEvent, bExitAppEvent);
+
+ bool bOk = false;
+ {
+ // Lock Mutex before handling events so that we don't disturb a running cmd
+ CMIUtilThreadLock lock(CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex());
+ bOk = CMICmnLLDBDebuggerHandleEvents::Instance().HandleEvent(event, bHandledEvent, bExitAppEvent);
+ }
if (!bHandledEvent)
{
const CMIUtilString msg(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_WRN_UNKNOWN_EVENT), event.GetBroadcasterClass()));
diff --git a/tools/lldb-mi/MICmnLLDBDebugger.h b/tools/lldb-mi/MICmnLLDBDebugger.h
index 6075fd85e535..403d71d0e32d 100644
--- a/tools/lldb-mi/MICmnLLDBDebugger.h
+++ b/tools/lldb-mi/MICmnLLDBDebugger.h
@@ -24,9 +24,9 @@
// Third party headers
#include <queue>
#include <map>
-#include <lldb/API/SBDebugger.h>
-#include <lldb/API/SBListener.h>
-#include <lldb/API/SBEvent.h>
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBListener.h"
+#include "lldb/API/SBEvent.h"
// In-house headers:
#include "MICmnBase.h"
diff --git a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
index b375611ec6ec..50049e643ec7 100644
--- a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
+++ b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
@@ -20,13 +20,13 @@
//--
// Third party headers:
-#include <lldb/API/SBEvent.h>
-#include <lldb/API/SBProcess.h>
-#include <lldb/API/SBBreakpoint.h>
-#include <lldb/API/SBStream.h>
-#include <lldb/API/SBThread.h>
-#include <lldb/API/SBCommandInterpreter.h>
-#include <lldb/API/SBCommandReturnObject.h>
+#include "lldb/API/SBEvent.h"
+#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBBreakpoint.h"
+#include "lldb/API/SBStream.h"
+#include "lldb/API/SBThread.h"
+#include "lldb/API/SBCommandInterpreter.h"
+#include "lldb/API/SBCommandReturnObject.h"
#ifdef _WIN32
#include <io.h> // For the ::_access()
#else
@@ -722,9 +722,9 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateSuspended(const lldb::SBE
return MIstatus::success;
bool bOk = MIstatus::success;
- lldb::SBDebugger &rDebugger = CMICmnLLDBDebugSessionInfo::Instance().m_rLldbDebugger;
- lldb::SBProcess &rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
- lldb::SBTarget target = rProcess.GetTarget();
+ lldb::SBDebugger &rDebugger = CMICmnLLDBDebugSessionInfo::Instance().GetDebugger();
+ lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
+ lldb::SBTarget target = sbProcess.GetTarget();
if (rDebugger.GetSelectedTarget() == target)
{
if (!UpdateSelectedThread())
@@ -768,8 +768,8 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateStopped(bool &vwrbShouldB
const MIchar *pEventType = "";
bool bOk = MIstatus::success;
- lldb::SBProcess &rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
- const lldb::StopReason eStoppedReason = rProcess.GetSelectedThread().GetStopReason();
+ lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
+ const lldb::StopReason eStoppedReason = sbProcess.GetSelectedThread().GetStopReason();
switch (eStoppedReason)
{
case lldb::eStopReasonInvalid:
@@ -807,6 +807,9 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateStopped(bool &vwrbShouldB
case lldb::eStopReasonThreadExiting:
pEventType = "eStopReasonThreadExiting";
break;
+ case lldb::eStopReasonInstrumentation:
+ pEventType = "eStopReasonInstrumentation";
+ break;
}
// ToDo: Remove when finished coding application
@@ -828,8 +831,8 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopSignal(bool &vwrbShouldBrk
{
bool bOk = MIstatus::success;
- lldb::SBProcess &rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
- const MIuint64 nStopReason = rProcess.GetSelectedThread().GetStopReasonDataAtIndex(0);
+ lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
+ const MIuint64 nStopReason = sbProcess.GetSelectedThread().GetStopReasonDataAtIndex(0);
switch (nStopReason)
{
case 2: // Terminal interrupt signal. SIGINT
@@ -865,7 +868,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopSignal(bool &vwrbShouldBrk
const CMICmnMIValueConst miValueConst3("Segmentation fault");
const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
bOk = bOk && miOutOfBandRecord.Add(miValueResult3);
- const CMIUtilString strThreadId(CMIUtilString::Format("%d", rProcess.GetSelectedThread().GetIndexID()));
+ const CMIUtilString strThreadId(CMIUtilString::Format("%d", sbProcess.GetSelectedThread().GetIndexID()));
const CMICmnMIValueConst miValueConst4(strThreadId);
const CMICmnMIValueResult miValueResult4("thread-id", miValueConst4);
bOk = bOk && miOutOfBandRecord.Add(miValueResult4);
@@ -878,12 +881,12 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopSignal(bool &vwrbShouldBrk
}
break;
case 19:
- if (rProcess.IsValid())
- rProcess.Continue();
+ if (sbProcess.IsValid())
+ sbProcess.Continue();
break;
case 5: // Trace/breakpoint trap. SIGTRAP
{
- lldb::SBThread thread = rProcess.GetSelectedThread();
+ lldb::SBThread thread = sbProcess.GetSelectedThread();
const MIuint nFrames = thread.GetNumFrames();
if (nFrames > 0)
{
@@ -896,9 +899,9 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopSignal(bool &vwrbShouldBrk
if (CMIUtilString::Compare(threadCloneFn, fnName))
{
- if (rProcess.IsValid())
+ if (sbProcess.IsValid())
{
- rProcess.Continue();
+ sbProcess.Continue();
vwrbShouldBrk = true;
break;
}
@@ -939,8 +942,8 @@ bool
CMICmnLLDBDebuggerHandleEvents::MiHelpGetCurrentThreadFrame(CMICmnMIValueTuple &vwrMiValueTuple)
{
CMIUtilString strThreadFrame;
- lldb::SBProcess &rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
- lldb::SBThread thread = rProcess.GetSelectedThread();
+ lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
+ lldb::SBThread thread = sbProcess.GetSelectedThread();
const MIuint nFrame = thread.GetNumFrames();
if (nFrame == 0)
{
@@ -994,9 +997,9 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonBreakpoint(void)
return MIstatus::failure;
}
- lldb::SBProcess &rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
- const MIuint64 brkPtId = rProcess.GetSelectedThread().GetStopReasonDataAtIndex(0);
- lldb::SBBreakpoint brkPt = CMICmnLLDBDebugSessionInfo::Instance().m_lldbTarget.GetBreakpointAtIndex((MIuint)brkPtId);
+ lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
+ const MIuint64 brkPtId = sbProcess.GetSelectedThread().GetStopReasonDataAtIndex(0);
+ lldb::SBBreakpoint brkPt = CMICmnLLDBDebugSessionInfo::Instance().GetTarget().GetBreakpointAtIndex((MIuint)brkPtId);
return MiStoppedAtBreakPoint(brkPtId, brkPt);
}
@@ -1015,8 +1018,8 @@ CMICmnLLDBDebuggerHandleEvents::MiStoppedAtBreakPoint(const MIuint64 vBrkPtId, c
{
bool bOk = MIstatus::success;
- lldb::SBProcess &rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
- lldb::SBThread thread = rProcess.GetSelectedThread();
+ lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
+ lldb::SBThread thread = sbProcess.GetSelectedThread();
const MIuint nFrame = thread.GetNumFrames();
if (nFrame == 0)
{
@@ -1078,7 +1081,7 @@ CMICmnLLDBDebuggerHandleEvents::MiStoppedAtBreakPoint(const MIuint64 vBrkPtId, c
{
CMICmnMIValueList miValueList(true);
const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Arguments;
- bOk = rSession.MIResponseFormVariableInfo2(frame, maskVarTypes, miValueList);
+ bOk = rSession.MIResponseFormVariableInfo2(frame, maskVarTypes, CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues, miValueList);
CMICmnMIValueTuple miValueTuple;
bOk = bOk && rSession.MIResponseFormFrameInfo2(pc, miValueList.GetString(), fnName, fileName, path, nLine, miValueTuple);
@@ -1118,8 +1121,8 @@ bool
CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonTrace(void)
{
bool bOk = true;
- lldb::SBProcess &rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
- lldb::SBThread thread = rProcess.GetSelectedThread();
+ lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
+ lldb::SBThread thread = sbProcess.GetSelectedThread();
const MIuint nFrame = thread.GetNumFrames();
if (nFrame == 0)
{
@@ -1154,7 +1157,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonTrace(void)
// Function args
CMICmnMIValueList miValueList(true);
const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Arguments;
- if (!rSession.MIResponseFormVariableInfo2(frame, maskVarTypes, miValueList))
+ if (!rSession.MIResponseFormVariableInfo2(frame, maskVarTypes, CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues, miValueList))
return MIstatus::failure;
CMICmnMIValueTuple miValueTuple;
if (!rSession.MIResponseFormFrameInfo2(pc, miValueList.GetString(), fnName, fileName, path, nLine, miValueTuple))
@@ -1197,7 +1200,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonTrace(void)
bool
CMICmnLLDBDebuggerHandleEvents::UpdateSelectedThread(void)
{
- lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().m_rLldbDebugger.GetSelectedTarget().GetProcess();
+ lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetDebugger().GetSelectedTarget().GetProcess();
if (!process.IsValid())
return MIstatus::success;
@@ -1339,7 +1342,7 @@ CMICmnLLDBDebuggerHandleEvents::GetProcessStdout(void)
char c;
size_t nBytes = 0;
CMIUtilString text;
- lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().m_rLldbDebugger.GetSelectedTarget().GetProcess();
+ lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetDebugger().GetSelectedTarget().GetProcess();
while (process.GetSTDOUT(&c, 1) > 0)
{
CMIUtilString str;
@@ -1374,7 +1377,7 @@ CMICmnLLDBDebuggerHandleEvents::GetProcessStderr(void)
char c;
size_t nBytes = 0;
CMIUtilString text;
- lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().m_rLldbDebugger.GetSelectedTarget().GetProcess();
+ lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetDebugger().GetSelectedTarget().GetProcess();
while (process.GetSTDERR(&c, 1) > 0)
{
CMIUtilString str;
@@ -1448,22 +1451,22 @@ CMICmnLLDBDebuggerHandleEvents::ConvertPrintfCtrlCodeToString(const MIchar vCtrl
bool
CMICmnLLDBDebuggerHandleEvents::ChkForStateChanges(void)
{
- lldb::SBProcess &rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
- if (!rProcess.IsValid())
+ lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
+ if (!sbProcess.IsValid())
return MIstatus::success;
- lldb::SBTarget &rTarget = CMICmnLLDBDebugSessionInfo::Instance().m_lldbTarget;
- if (!rTarget.IsValid())
+ lldb::SBTarget sbTarget = CMICmnLLDBDebugSessionInfo::Instance().GetTarget();
+ if (!sbTarget.IsValid())
return MIstatus::success;
bool bOk = MIstatus::success;
// Check for created threads
- const MIuint nThread = rProcess.GetNumThreads();
+ const MIuint nThread = sbProcess.GetNumThreads();
for (MIuint i = 0; i < nThread; i++)
{
// GetThreadAtIndex() uses a base 0 index
// GetThreadByIndexID() uses a base 1 index
- lldb::SBThread thread = rProcess.GetThreadAtIndex(i);
+ lldb::SBThread thread = sbProcess.GetThreadAtIndex(i);
if (!thread.IsValid())
continue;
@@ -1500,7 +1503,7 @@ CMICmnLLDBDebuggerHandleEvents::ChkForStateChanges(void)
}
}
- lldb::SBThread currentThread = rProcess.GetSelectedThread();
+ lldb::SBThread currentThread = sbProcess.GetSelectedThread();
if (currentThread.IsValid())
{
const MIuint threadId = currentThread.GetIndexID();
@@ -1523,7 +1526,7 @@ CMICmnLLDBDebuggerHandleEvents::ChkForStateChanges(void)
while (it != CMICmnLLDBDebugSessionInfo::Instance().m_vecActiveThreadId.end())
{
const MIuint nThreadId = *it;
- lldb::SBThread thread = rProcess.GetThreadAtIndex(nThreadId);
+ lldb::SBThread thread = sbProcess.GetThreadAtIndex(nThreadId);
if (!thread.IsValid())
{
// Form MI "=thread-exited,id=\"%ld\",group-id=\"i1\""
diff --git a/tools/lldb-mi/MICmnLLDBProxySBValue.cpp b/tools/lldb-mi/MICmnLLDBProxySBValue.cpp
index a4f36b400fa7..6a07f207840e 100644
--- a/tools/lldb-mi/MICmnLLDBProxySBValue.cpp
+++ b/tools/lldb-mi/MICmnLLDBProxySBValue.cpp
@@ -22,7 +22,7 @@
#include <stdlib.h>
// Third Party Headers:
-#include <lldb/API/SBError.h>
+#include "lldb/API/SBError.h"
// In-house headers:
#include "MICmnLLDBProxySBValue.h"
@@ -129,14 +129,14 @@ CMICmnLLDBProxySBValue::GetCString(const lldb::SBValue &vrValue, CMIUtilString &
return MIstatus::failure;
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess &rProcess = rSessionInfo.m_lldbProcess;
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
MIuint nBufferSize = 64;
bool bNeedResize = false;
MIchar *pBuffer = static_cast<MIchar *>(::malloc(nBufferSize));
do
{
lldb::SBError error;
- const size_t nReadSize = rProcess.ReadCStringFromMemory((lldb::addr_t)nNum, pBuffer, nBufferSize, error);
+ const size_t nReadSize = sbProcess.ReadCStringFromMemory((lldb::addr_t)nNum, pBuffer, nBufferSize, error);
if (nReadSize == (nBufferSize - 1))
{
bNeedResize = true;
diff --git a/tools/lldb-mi/MICmnLLDBProxySBValue.h b/tools/lldb-mi/MICmnLLDBProxySBValue.h
index e21eb95a2dd9..39befe9566f3 100644
--- a/tools/lldb-mi/MICmnLLDBProxySBValue.h
+++ b/tools/lldb-mi/MICmnLLDBProxySBValue.h
@@ -22,7 +22,7 @@
#pragma once
// Third Party Headers:
-#include <lldb/API/SBValue.h>
+#include "lldb/API/SBValue.h"
// In-house headers:
#include "MIDataTypes.h"
diff --git a/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp b/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp
index 847bba2c8d0a..66a4efd5a96e 100644
--- a/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp
+++ b/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp
@@ -219,7 +219,7 @@ CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory(const lldb::SBValue &vrValueObj
const MIuint nBytes(128);
const MIchar *pBufferMemory = new MIchar[nBytes];
lldb::SBError error;
- const MIuint64 nReadBytes = rSessionInfo.m_lldbProcess.ReadMemory(addr, (void *)pBufferMemory, nBytes, error);
+ const MIuint64 nReadBytes = rSessionInfo.GetProcess().ReadMemory(addr, (void *)pBufferMemory, nBytes, error);
MIunused(nReadBytes);
text = CMIUtilString::Format("\\\"%s\\\"", pBufferMemory);
delete[] pBufferMemory;
diff --git a/tools/lldb-mi/MICmnLLDBUtilSBValue.h b/tools/lldb-mi/MICmnLLDBUtilSBValue.h
index 1aa3022960b7..a3f2c9c0ffc9 100644
--- a/tools/lldb-mi/MICmnLLDBUtilSBValue.h
+++ b/tools/lldb-mi/MICmnLLDBUtilSBValue.h
@@ -22,7 +22,7 @@
#pragma once
// Third Party Headers:
-#include <lldb/API/SBValue.h>
+#include "lldb/API/SBValue.h"
// In-house headers:
#include "MIDataTypes.h"
diff --git a/tools/lldb-mi/MICmnLog.cpp b/tools/lldb-mi/MICmnLog.cpp
index a18fd2d4e502..dc7a93d29776 100644
--- a/tools/lldb-mi/MICmnLog.cpp
+++ b/tools/lldb-mi/MICmnLog.cpp
@@ -73,7 +73,6 @@ CMICmnLog::Initialize(void)
// Mediums set inside because explicitly initing in MIDriverMain.cpp causes compile errors with CAtlFile
CMICmnLogMediumFile &rFileLog(CMICmnLogMediumFile::Instance());
bool bOk = RegisterMedium(rFileLog);
- bOk = bOk && SetEnabled(true);
if (bOk)
{
// Set the Log trace file's header
diff --git a/tools/lldb-mi/MICmnResources.cpp b/tools/lldb-mi/MICmnResources.cpp
index 676e9e743986..bc1fa3025cd6 100644
--- a/tools/lldb-mi/MICmnResources.cpp
+++ b/tools/lldb-mi/MICmnResources.cpp
@@ -82,7 +82,7 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{IDE_MI_APP_ARG_EXECUTEABLE, "--executable\n\tUse the MI Driver in MI mode for the debugging the specified\n\texecutable. Any LLDB "
"command line options are ignored even\n\tif the MI Driver falls through to the LLDB driver. "
"(Depends\n\ton the build configuration see MICmnConfig.h)\n\tNormally specified from the command line."},
- {IDE_MI_APP_ARG_NO_APP_LOG, "--noLog\n\tUse this argument to tell the MI Driver not to update it's log\n\tfile '%s'."},
+ {IDE_MI_APP_ARG_APP_LOG, "--log\n\tUse this argument to tell the MI Driver to update it's log\n\tfile '%s'."},
{IDE_MI_APP_ARG_EXAMPLE, "Example MI command:\n\t3-info-gdb-mi-command gdb-set\n\t3^done,command={exists=\"true\"}"},
{IDE_MI_APP_ARG_EXECUTABLE, "executable (NOT IMPLEMENTED)\n\tThe file path to the executable i.e. '\"C:\\My Dev\\foo.exe\"'."},
{IDS_STDIN_ERR_INVALID_PROMPT, "Stdin. Invalid prompt description '%s'"},
@@ -254,6 +254,7 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{IDS_CMD_ERR_LLDB_ERR_NOT_READ_WHOLE_BLK, "Command '%s'. LLDB unable to read entire memory block of %u bytes at address 0x%08x"},
{IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES, "Command '%s'. Unable to read memory block of %u bytes at address 0x%08x: %s "},
{IDS_CMD_ERR_INVALID_PROCESS, "Command '%s'. Invalid process during debug session"},
+ {IDS_CMD_ERR_INVALID_PRINT_VALUES, "Command '%s'. Unknown value for PRINT_VALUES: must be: 0 or \"--no-values\", 1 or \"all-values\", 2 or \"simple-values\""},
{IDS_CMD_ERR_INVALID_FORMAT_TYPE, "Command '%s'. Invalid var format type '%s'"},
{IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND, "Command '%s'. Breakpoint information for breakpoint ID %d not found"},
{IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES, "Command '%s'. Unable to write memory block of %u bytes at address 0x%08x: %s "},
diff --git a/tools/lldb-mi/MICmnResources.h b/tools/lldb-mi/MICmnResources.h
index cd9208cfb7a4..b561473fbb79 100644
--- a/tools/lldb-mi/MICmnResources.h
+++ b/tools/lldb-mi/MICmnResources.h
@@ -89,7 +89,7 @@ enum
IDE_MI_APP_ARG_VERSION_LONG,
IDE_MI_APP_ARG_INTERPRETER,
IDE_MI_APP_ARG_EXECUTEABLE,
- IDE_MI_APP_ARG_NO_APP_LOG,
+ IDE_MI_APP_ARG_APP_LOG,
IDE_MI_APP_ARG_EXAMPLE,
IDE_MI_APP_ARG_EXECUTABLE,
@@ -270,6 +270,7 @@ enum
IDS_CMD_ERR_LLDB_ERR_NOT_READ_WHOLE_BLK,
IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES,
IDS_CMD_ERR_INVALID_PROCESS,
+ IDS_CMD_ERR_INVALID_PRINT_VALUES,
IDS_CMD_ERR_INVALID_FORMAT_TYPE,
IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND,
IDS_CMD_ERR_LLDB_ERR_WRITE_MEM_BYTES,
diff --git a/tools/lldb-mi/MIDriver.cpp b/tools/lldb-mi/MIDriver.cpp
index accde1c7cde7..5628e344952b 100644
--- a/tools/lldb-mi/MIDriver.cpp
+++ b/tools/lldb-mi/MIDriver.cpp
@@ -22,7 +22,7 @@
// Third party headers:
#include <stdarg.h> // va_list, va_start, var_end
#include <iostream>
-#include <lldb/API/SBError.h>
+#include "lldb/API/SBError.h"
// In-house headers:
#include "Driver.h"
@@ -41,6 +41,7 @@
#include "MICmdArgValFile.h"
#include "MICmdArgValString.h"
#include "MICmnConfig.h"
+#include "MICmnLLDBDebugSessionInfo.h"
// Instantiations:
#if _DEBUG
@@ -687,7 +688,13 @@ CMIDriver::ReadStdinLineQueue(void)
}
// Process the command
- const bool bOk = InterpretCommand(lineText);
+ bool bOk = false;
+ {
+ // Lock Mutex before processing commands so that we don't disturb an event
+ // that is being processed.
+ CMIUtilThreadLock lock(CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex());
+ bOk = InterpretCommand(lineText);
+ }
// Draw prompt if desired
if (bOk && m_rStdin.GetEnablePrompt())
diff --git a/tools/lldb-mi/MIDriverBase.cpp b/tools/lldb-mi/MIDriverBase.cpp
index fd9fae821196..fd1a0eca5536 100644
--- a/tools/lldb-mi/MIDriverBase.cpp
+++ b/tools/lldb-mi/MIDriverBase.cpp
@@ -20,8 +20,8 @@
//--
// Third party headers:
-#include <lldb/API/SBEvent.h>
-#include <lldb/API/SBBroadcaster.h>
+#include "lldb/API/SBEvent.h"
+#include "lldb/API/SBBroadcaster.h"
// In-house headers:
#include "MIDriverBase.h"
diff --git a/tools/lldb-mi/MIDriverBase.h b/tools/lldb-mi/MIDriverBase.h
index 7516efd13b75..25ac23887282 100644
--- a/tools/lldb-mi/MIDriverBase.h
+++ b/tools/lldb-mi/MIDriverBase.h
@@ -22,8 +22,8 @@
#pragma once
// Third party headers:
-#include <lldb/API/SBDebugger.h>
-#include <lldb/API/SBBroadcaster.h>
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBBroadcaster.h"
// In-house headers:
#include "MIUtilString.h"
diff --git a/tools/lldb-mi/MIDriverMain.cpp b/tools/lldb-mi/MIDriverMain.cpp
index b14fb815b6e6..5557799d3680 100644
--- a/tools/lldb-mi/MIDriverMain.cpp
+++ b/tools/lldb-mi/MIDriverMain.cpp
@@ -49,7 +49,7 @@
// Third party headers:
#include <stdio.h>
-#include <lldb/API/SBHostOS.h>
+#include "lldb/API/SBHostOS.h"
// In house headers:
#include "MICmnConfig.h"
@@ -81,6 +81,9 @@
void
sigwinch_handler(int vSigno)
{
+#ifdef _WIN32 // Restore handler as it is not persistent on Windows
+ signal(SIGWINCH, sigwinch_handler);
+#endif
MIunused(vSigno);
struct winsize window_size;
@@ -111,6 +114,9 @@ sigwinch_handler(int vSigno)
void
sigint_handler(int vSigno)
{
+#ifdef _WIN32 // Restore handler as it is not persistent on Windows
+ signal(SIGINT, sigint_handler);
+#endif
static bool g_interrupt_sent = false;
CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
lldb::SBDebugger *pDebugger = rDriverMgr.DriverGetTheDebugger();
@@ -147,6 +153,9 @@ sigint_handler(int vSigno)
void
sigtstp_handler(int vSigno)
{
+#ifdef _WIN32 // Restore handler as it is not persistent on Windows
+ signal(SIGTSTP, sigtstp_handler);
+#endif
CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
lldb::SBDebugger *pDebugger = rDriverMgr.DriverGetTheDebugger();
if (pDebugger != nullptr)
@@ -175,6 +184,9 @@ sigtstp_handler(int vSigno)
void
sigcont_handler(int vSigno)
{
+#ifdef _WIN32 // Restore handler as it is not persistent on Windows
+ signal(SIGCONT, sigcont_handler);
+#endif
CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
lldb::SBDebugger *pDebugger = rDriverMgr.DriverGetTheDebugger();
if (pDebugger != nullptr)
diff --git a/tools/lldb-mi/MIDriverMgr.cpp b/tools/lldb-mi/MIDriverMgr.cpp
index 79b44ca947ad..ca900ca6e885 100644
--- a/tools/lldb-mi/MIDriverMgr.cpp
+++ b/tools/lldb-mi/MIDriverMgr.cpp
@@ -20,7 +20,7 @@
//--
// Third Party Headers:
-#include <lldb/API/SBError.h>
+#include "lldb/API/SBError.h"
// In-house headers:
#include "MIDriverMgr.h"
@@ -125,8 +125,6 @@ CMIDriverMgr::Shutdown(void)
if (vbAppExitOk)
{
- // The MI Driver's log updating may have been switched off switch back on to say all is ok.
- CMICmnLog::Instance().SetEnabled(true);
#if _DEBUG
CMICmnStreamStdout::Instance().Write(MIRSRC(IDE_MI_APP_EXIT_OK)); // Both stdout and Log
#else
@@ -144,8 +142,6 @@ CMIDriverMgr::Shutdown(void)
}
else
{
- // The MI Driver's log updating may have been switched off switch back on to say there has been problem.
- rAppLog.SetEnabled(true);
const CMIUtilString msg(
CMIUtilString::Format(MIRSRC(IDE_MI_APP_EXIT_WITH_PROBLEM_NO_LOG), CMICmnLogMediumFile::Instance().GetFileName().c_str()));
CMICmnStreamStdout::Instance().Write(msg);
@@ -495,7 +491,7 @@ CMIDriverMgr::DriverGetTheDebugger(void)
// --interpreter
// --version
// --versionLong
-// --noLog
+// --log
// --executable
// The above arguments are not handled by any driver object except for --executable.
// The options --interpreter and --executable in code act very similar. The
@@ -552,7 +548,7 @@ CMIDriverMgr::ParseArgs(const int argc, const char *argv[], bool &vwbExiting)
bool bHaveArgInterpret = false;
bool bHaveArgVersion = false;
bool bHaveArgVersionLong = false;
- bool bHaveArgNoLog = false;
+ bool bHaveArgLog = false;
bool bHaveArgHelp = false;
// Hardcode the use of the MI driver
@@ -582,9 +578,9 @@ CMIDriverMgr::ParseArgs(const int argc, const char *argv[], bool &vwbExiting)
{
bHaveArgVersionLong = true;
}
- if (0 == strArg.compare("--noLog"))
+ if (0 == strArg.compare("--log"))
{
- bHaveArgNoLog = true;
+ bHaveArgLog = true;
}
if ((0 == strArg.compare("--help")) || (0 == strArg.compare("-h")))
{
@@ -593,9 +589,9 @@ CMIDriverMgr::ParseArgs(const int argc, const char *argv[], bool &vwbExiting)
}
}
- if (bHaveArgNoLog)
+ if (bHaveArgLog)
{
- CMICmnLog::Instance().SetEnabled(false);
+ CMICmnLog::Instance().SetEnabled(true);
}
// Todo: Remove this output when MI is finished. It is temporary to persuade Ecllipse plugin to work.
@@ -687,7 +683,7 @@ CMIDriverMgr::GetHelpOnCmdLineArgOptions(void) const
MIRSRC(IDE_MI_APP_ARG_VERSION_LONG),
MIRSRC(IDE_MI_APP_ARG_INTERPRETER),
MIRSRC(IDE_MI_APP_ARG_EXECUTEABLE),
- CMIUtilString::Format(MIRSRC(IDE_MI_APP_ARG_NO_APP_LOG), CMICmnLogMediumFile::Instance().GetFileName().c_str()),
+ CMIUtilString::Format(MIRSRC(IDE_MI_APP_ARG_APP_LOG), CMICmnLogMediumFile::Instance().GetFileName().c_str()),
MIRSRC(IDE_MI_APP_ARG_EXECUTABLE),
MIRSRC(IDS_CMD_QUIT_HELP),
MIRSRC(IDE_MI_APP_ARG_EXAMPLE)};
diff --git a/tools/lldb-mi/MIDriverMgr.h b/tools/lldb-mi/MIDriverMgr.h
index d9449277b063..9e1e121405cb 100644
--- a/tools/lldb-mi/MIDriverMgr.h
+++ b/tools/lldb-mi/MIDriverMgr.h
@@ -23,7 +23,7 @@
// Third party headers:
#include <map>
-#include <lldb/API/SBDebugger.h>
+#include "lldb/API/SBDebugger.h"
// In-house headers:
#include "MICmnBase.h"
diff --git a/tools/lldb-mi/MIReadMe.txt b/tools/lldb-mi/MIReadMe.txt
index fbd3b2d364f6..47d28e395ede 100644
--- a/tools/lldb-mi/MIReadMe.txt
+++ b/tools/lldb-mi/MIReadMe.txt
@@ -1,5 +1,5 @@
========================================================================
- The MI Driver - LLDB Machine Interface V2 (MI) Project Overview
+ The MI Driver - LLDB Machine Interface V2 (MI) Project Overview
24/07/2014
========================================================================