From 0cac4ca3916ac24ab6139d03cbfd18db9e715bfe Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Tue, 25 Nov 2014 21:00:58 +0000 Subject: Import LLDB as of upstream SVN r216948 (git 50f7fe44) This corresponds with the branchpoint for the 3.5 release. A number of files not required for the FreeBSD build have been removed. Sponsored by: DARPA, AFRL --- include/lldb/API/SBBreakpoint.h | 8 +- include/lldb/API/SBBreakpointLocation.h | 6 + include/lldb/API/SBDefines.h | 111 +- include/lldb/API/SBError.h | 2 + include/lldb/API/SBExpressionOptions.h | 34 + include/lldb/API/SBFileSpec.h | 2 +- include/lldb/API/SBFrame.h | 2 +- include/lldb/API/SBHostOS.h | 7 +- include/lldb/API/SBListener.h | 2 +- include/lldb/API/SBProcess.h | 6 + include/lldb/API/SBQueue.h | 8 +- include/lldb/API/SBQueueItem.h | 1 - include/lldb/API/SBStream.h | 3 +- include/lldb/API/SBTarget.h | 45 +- include/lldb/API/SBThread.h | 13 +- include/lldb/API/SBType.h | 8 + include/lldb/API/SBTypeEnumMember.h | 98 + include/lldb/API/SBUnixSignals.h | 84 + include/lldb/API/SBValue.h | 7 +- include/lldb/Breakpoint/Breakpoint.h | 2 +- include/lldb/Breakpoint/BreakpointLocationList.h | 2 +- include/lldb/Breakpoint/BreakpointOptions.h | 5 +- include/lldb/Breakpoint/BreakpointSite.h | 11 +- include/lldb/Breakpoint/Watchpoint.h | 4 +- include/lldb/Core/Address.h | 6 +- include/lldb/Core/AddressRange.h | 4 +- include/lldb/Core/ArchSpec.h | 46 +- include/lldb/Core/ClangForward.h | 1 + include/lldb/Core/Communication.h | 4 +- include/lldb/Core/ConnectionFileDescriptor.h | 88 +- include/lldb/Core/ConstString.h | 8 +- include/lldb/Core/DataBuffer.h | 2 +- include/lldb/Core/DataBufferHeap.h | 3 + include/lldb/Core/DataBufferMemoryMap.h | 11 +- include/lldb/Core/DataEncoder.h | 6 +- include/lldb/Core/Debugger.h | 24 +- include/lldb/Core/EmulateInstruction.h | 20 +- include/lldb/Core/Error.h | 9 +- include/lldb/Core/IOHandler.h | 49 +- include/lldb/Core/Listener.h | 2 +- include/lldb/Core/Mangled.h | 6 +- include/lldb/Core/Module.h | 58 +- include/lldb/Core/ModuleList.h | 15 +- include/lldb/Core/ModuleSpec.h | 6 +- include/lldb/Core/PluginManager.h | 23 +- include/lldb/Core/RegisterValue.h | 6 + include/lldb/Core/RegularExpression.h | 12 +- include/lldb/Core/Section.h | 14 + include/lldb/Core/SourceManager.h | 2 +- include/lldb/Core/Stream.h | 2 +- include/lldb/Core/StructuredData.h | 486 ++ include/lldb/Core/UserID.h | 6 +- include/lldb/Core/Value.h | 25 +- include/lldb/Core/ValueObject.h | 35 +- include/lldb/Core/ValueObjectChild.h | 5 +- include/lldb/Core/ValueObjectConstResult.h | 3 + include/lldb/Core/ValueObjectDynamicValue.h | 3 + include/lldb/Core/ValueObjectMemory.h | 3 + include/lldb/Core/ValueObjectRegister.h | 3 + include/lldb/Core/ValueObjectSyntheticFilter.h | 3 + include/lldb/Core/ValueObjectVariable.h | 3 + include/lldb/Core/dwarf.h | 2 +- .../lldb/DataFormatters/CXXFormatterFunctions.h | 114 +- include/lldb/DataFormatters/FormatManager.h | 27 +- include/lldb/DataFormatters/TypeFormat.h | 9 +- include/lldb/DataFormatters/TypeSummary.h | 18 +- include/lldb/DataFormatters/ValueObjectPrinter.h | 2 +- include/lldb/Expression/ASTStructExtractor.h | 2 +- include/lldb/Expression/ClangExpressionDeclMap.h | 8 +- include/lldb/Expression/ClangExpressionParser.h | 15 +- include/lldb/Expression/ClangExpressionVariable.h | 10 +- include/lldb/Expression/ClangFunction.h | 14 +- include/lldb/Expression/ClangUserExpression.h | 23 +- include/lldb/Expression/ClangUtilityFunction.h | 8 +- include/lldb/Expression/DWARFExpression.h | 13 +- include/lldb/Expression/ExpressionSourceCode.h | 5 +- include/lldb/Expression/IRExecutionUnit.h | 87 +- include/lldb/Expression/IRForTarget.h | 12 +- include/lldb/Expression/IRMemoryMap.h | 12 +- include/lldb/Host/Condition.h | 2 +- include/lldb/Host/Config.h | 2 +- include/lldb/Host/Debug.h | 244 +- include/lldb/Host/DynamicLibrary.h | 51 - include/lldb/Host/Editline.h | 51 +- include/lldb/Host/Endian.h | 2 +- include/lldb/Host/File.h | 20 +- include/lldb/Host/FileCache.h | 45 + include/lldb/Host/FileSpec.h | 78 +- include/lldb/Host/FileSystem.h | 43 + include/lldb/Host/Host.h | 257 +- include/lldb/Host/HostGetOpt.h | 6 +- include/lldb/Host/HostInfo.h | 61 + include/lldb/Host/HostInfoBase.h | 119 + include/lldb/Host/HostProcess.h | 44 + include/lldb/Host/IOObject.h | 61 + include/lldb/Host/OptionParser.h | 13 +- include/lldb/Host/Pipe.h | 83 + include/lldb/Host/Predicate.h | 12 +- include/lldb/Host/Socket.h | 103 + include/lldb/Host/SocketAddress.h | 6 +- include/lldb/Host/Symbols.h | 2 +- include/lldb/Host/Terminal.h | 2 +- include/lldb/Host/TimeValue.h | 6 +- include/lldb/Host/freebsd/HostInfoFreeBSD.h | 29 + include/lldb/Host/posix/HostInfoPosix.h | 40 + include/lldb/Host/posix/HostProcessPosix.h | 46 + include/lldb/Interpreter/Args.h | 6 +- include/lldb/Interpreter/CommandCompletions.h | 2 +- include/lldb/Interpreter/CommandInterpreter.h | 10 +- include/lldb/Interpreter/CommandObject.h | 33 +- include/lldb/Interpreter/CommandOptionValidators.h | 30 + include/lldb/Interpreter/CommandReturnObject.h | 13 +- include/lldb/Interpreter/Options.h | 8 +- include/lldb/Interpreter/PythonDataObjects.h | 6 +- include/lldb/Interpreter/ScriptInterpreter.h | 51 +- include/lldb/Interpreter/ScriptInterpreterPython.h | 41 +- include/lldb/Symbol/Block.h | 12 +- include/lldb/Symbol/ClangASTContext.h | 38 +- include/lldb/Symbol/ClangASTImporter.h | 2 +- include/lldb/Symbol/ClangASTType.h | 19 +- include/lldb/Symbol/ClangExternalASTSourceCommon.h | 2 +- include/lldb/Symbol/CompileUnit.h | 8 +- include/lldb/Symbol/DWARFCallFrameInfo.h | 2 +- include/lldb/Symbol/Declaration.h | 4 +- include/lldb/Symbol/FuncUnwinders.h | 11 +- include/lldb/Symbol/Function.h | 16 +- include/lldb/Symbol/LineEntry.h | 4 +- include/lldb/Symbol/LineTable.h | 4 +- include/lldb/Symbol/ObjectContainer.h | 4 +- include/lldb/Symbol/ObjectFile.h | 97 +- include/lldb/Symbol/Symbol.h | 15 +- include/lldb/Symbol/SymbolContext.h | 8 +- include/lldb/Symbol/SymbolContextScope.h | 6 +- include/lldb/Symbol/SymbolFile.h | 12 +- include/lldb/Symbol/SymbolVendor.h | 7 + include/lldb/Symbol/Symtab.h | 1 + include/lldb/Symbol/Type.h | 174 +- include/lldb/Symbol/UnwindPlan.h | 3 + include/lldb/Symbol/UnwindTable.h | 9 +- include/lldb/Symbol/VariableList.h | 4 +- include/lldb/Target/ABI.h | 63 +- include/lldb/Target/CPPLanguageRuntime.h | 2 +- include/lldb/Target/ExecutionContext.h | 38 +- include/lldb/Target/ExecutionContextScope.h | 2 +- include/lldb/Target/FileAction.h | 68 + include/lldb/Target/JITLoader.h | 90 + include/lldb/Target/JITLoaderList.h | 60 + include/lldb/Target/MemoryRegionInfo.h | 104 + include/lldb/Target/NativeRegisterContext.h | 190 + .../Target/NativeRegisterContextRegisterInfo.h | 44 + include/lldb/Target/ObjCLanguageRuntime.h | 41 +- include/lldb/Target/PathMappingList.h | 2 +- include/lldb/Target/Platform.h | 84 +- include/lldb/Target/Process.h | 977 +--- include/lldb/Target/ProcessInfo.h | 188 + include/lldb/Target/ProcessLaunchInfo.h | 225 + include/lldb/Target/Queue.h | 13 + include/lldb/Target/QueueItem.h | 53 +- include/lldb/Target/QueueList.h | 4 +- include/lldb/Target/RegisterContext.h | 43 +- include/lldb/Target/StackFrame.h | 6 +- include/lldb/Target/StopInfo.h | 7 +- include/lldb/Target/SystemRuntime.h | 79 +- include/lldb/Target/Target.h | 79 +- include/lldb/Target/TargetList.h | 2 +- include/lldb/Target/Thread.h | 256 +- include/lldb/Target/ThreadPlan.h | 38 + include/lldb/Target/ThreadPlanCallFunction.h | 8 +- include/lldb/Target/ThreadPlanCallUserExpression.h | 26 +- include/lldb/Target/ThreadPlanShouldStopHere.h | 85 +- include/lldb/Target/ThreadPlanStepInRange.h | 39 +- include/lldb/Target/ThreadPlanStepInstruction.h | 2 + include/lldb/Target/ThreadPlanStepOut.h | 27 +- include/lldb/Target/ThreadPlanStepOverRange.h | 19 +- include/lldb/Target/ThreadPlanStepRange.h | 1 + include/lldb/Target/UnwindAssembly.h | 5 + include/lldb/Utility/CleanUp.h | 6 +- include/lldb/Utility/PseudoTerminal.h | 4 +- include/lldb/Utility/SafeMachO.h | 113 + include/lldb/Utility/SharedCluster.h | 23 +- include/lldb/Utility/SharingPtr.h | 15 +- include/lldb/Utility/StringLexer.h | 62 + include/lldb/lldb-defines.h | 23 +- include/lldb/lldb-enumerations.h | 137 +- include/lldb/lldb-forward.h | 13 +- include/lldb/lldb-private-enumerations.h | 46 +- include/lldb/lldb-private-forward.h | 41 + include/lldb/lldb-private-interfaces.h | 6 +- include/lldb/lldb-private-log.h | 1 + include/lldb/lldb-private-types.h | 16 +- include/lldb/lldb-python.h | 16 +- include/lldb/lldb-types.h | 41 +- source/API/SBAddress.cpp | 8 +- source/API/SBBreakpoint.cpp | 117 +- source/API/SBBreakpointLocation.cpp | 57 +- source/API/SBBroadcaster.cpp | 18 +- source/API/SBCommandInterpreter.cpp | 58 +- source/API/SBCommandReturnObject.cpp | 14 +- source/API/SBCommunication.cpp | 52 +- source/API/SBCompileUnit.cpp | 31 +- source/API/SBData.cpp | 182 +- source/API/SBDebugger.cpp | 153 +- source/API/SBDeclaration.cpp | 21 +- source/API/SBError.cpp | 12 +- source/API/SBEvent.cpp | 19 +- source/API/SBExpressionOptions.cpp | 61 + source/API/SBFileSpec.cpp | 30 +- source/API/SBFileSpecList.cpp | 3 +- source/API/SBFrame.cpp | 169 +- source/API/SBFunction.cpp | 12 +- source/API/SBHostOS.cpp | 26 +- source/API/SBLineEntry.cpp | 20 +- source/API/SBListener.cpp | 38 +- source/API/SBModule.cpp | 49 +- source/API/SBProcess.cpp | 348 +- source/API/SBQueue.cpp | 136 +- source/API/SBQueueItem.cpp | 60 +- source/API/SBStream.cpp | 2 + source/API/SBSymbol.cpp | 6 +- source/API/SBSymbolContext.cpp | 28 +- source/API/SBTarget.cpp | 453 +- source/API/SBThread.cpp | 374 +- source/API/SBType.cpp | 32 + source/API/SBTypeEnumMember.cpp | 192 + source/API/SBUnixSignals.cpp | 199 + source/API/SBValue.cpp | 406 +- source/API/SBValueList.cpp | 16 +- source/API/SBWatchpoint.cpp | 13 +- source/Breakpoint/Breakpoint.cpp | 2 +- source/Breakpoint/BreakpointID.cpp | 2 +- source/Breakpoint/BreakpointList.cpp | 2 +- source/Breakpoint/BreakpointLocation.cpp | 19 +- source/Breakpoint/BreakpointLocationList.cpp | 2 +- source/Breakpoint/BreakpointOptions.cpp | 2 +- source/Breakpoint/BreakpointResolverName.cpp | 4 +- source/Breakpoint/BreakpointSite.cpp | 11 +- source/Breakpoint/BreakpointSiteList.cpp | 2 +- source/Breakpoint/WatchpointList.cpp | 2 +- source/Commands/CommandCompletions.cpp | 31 +- source/Commands/CommandObjectArgs.cpp | 14 +- source/Commands/CommandObjectBreakpoint.cpp | 95 +- source/Commands/CommandObjectBreakpointCommand.cpp | 151 +- source/Commands/CommandObjectCommands.cpp | 41 +- source/Commands/CommandObjectDisassemble.cpp | 197 +- source/Commands/CommandObjectExpression.cpp | 94 +- source/Commands/CommandObjectExpression.h | 3 + source/Commands/CommandObjectFrame.cpp | 10 +- source/Commands/CommandObjectHelp.cpp | 6 +- source/Commands/CommandObjectLog.cpp | 20 +- source/Commands/CommandObjectMemory.cpp | 38 +- source/Commands/CommandObjectPlatform.cpp | 89 +- source/Commands/CommandObjectProcess.cpp | 144 +- source/Commands/CommandObjectQuit.cpp | 2 +- source/Commands/CommandObjectRegister.cpp | 11 +- source/Commands/CommandObjectSettings.cpp | 9 +- source/Commands/CommandObjectSource.cpp | 30 +- source/Commands/CommandObjectTarget.cpp | 749 ++-- source/Commands/CommandObjectThread.cpp | 303 +- source/Commands/CommandObjectType.cpp | 190 +- source/Commands/CommandObjectWatchpoint.cpp | 46 +- source/Commands/CommandObjectWatchpointCommand.cpp | 10 +- source/Core/Address.cpp | 2 +- source/Core/AddressRange.cpp | 5 +- source/Core/AddressResolverName.cpp | 2 +- source/Core/ArchSpec.cpp | 190 +- source/Core/Broadcaster.cpp | 32 +- source/Core/Communication.cpp | 16 +- source/Core/ConnectionFileDescriptor.cpp | 1483 ++---- source/Core/ConnectionMachPort.cpp | 4 +- source/Core/ConnectionSharedMemory.cpp | 12 +- source/Core/ConstString.cpp | 5 +- source/Core/DataBufferHeap.cpp | 6 + source/Core/DataBufferMemoryMap.cpp | 94 +- source/Core/DataExtractor.cpp | 55 +- source/Core/Debugger.cpp | 469 +- source/Core/EmulateInstruction.cpp | 16 +- source/Core/Error.cpp | 31 +- source/Core/Event.cpp | 17 +- source/Core/FastDemangle.cpp | 2203 +++++++++ source/Core/IOHandler.cpp | 576 ++- source/Core/Language.cpp | 4 +- source/Core/Listener.cpp | 68 +- source/Core/Log.cpp | 2 +- source/Core/Mangled.cpp | 29 +- source/Core/Module.cpp | 199 +- source/Core/ModuleList.cpp | 59 +- source/Core/Opcode.cpp | 2 +- source/Core/PluginManager.cpp | 198 +- source/Core/RegularExpression.cpp | 8 +- source/Core/Scalar.cpp | 22 +- source/Core/SearchFilter.cpp | 2 +- source/Core/Section.cpp | 36 +- source/Core/SourceManager.cpp | 2 +- source/Core/Stream.cpp | 4 +- source/Core/StructuredData.cpp | 429 ++ source/Core/Value.cpp | 98 +- source/Core/ValueObject.cpp | 145 +- source/Core/ValueObjectChild.cpp | 52 +- source/Core/ValueObjectConstResult.cpp | 6 + source/Core/ValueObjectConstResultImpl.cpp | 6 +- source/Core/ValueObjectDynamicValue.cpp | 64 +- source/Core/ValueObjectMemory.cpp | 8 + source/Core/ValueObjectRegister.cpp | 6 + source/Core/ValueObjectSyntheticFilter.cpp | 6 + source/Core/ValueObjectVariable.cpp | 9 + source/DataFormatters/CF.cpp | 6 +- source/DataFormatters/CXXFormatterFunctions.cpp | 116 +- source/DataFormatters/Cocoa.cpp | 6 +- source/DataFormatters/FormatManager.cpp | 149 +- source/DataFormatters/LibCxx.cpp | 10 +- source/DataFormatters/LibCxxList.cpp | 56 +- source/DataFormatters/LibCxxMap.cpp | 10 +- source/DataFormatters/LibCxxUnorderedMap.cpp | 7 +- source/DataFormatters/LibStdcpp.cpp | 2 +- source/DataFormatters/NSArray.cpp | 384 +- source/DataFormatters/NSDictionary.cpp | 12 +- source/DataFormatters/NSSet.cpp | 6 +- source/DataFormatters/TypeFormat.cpp | 28 +- source/DataFormatters/TypeSummary.cpp | 23 +- source/DataFormatters/TypeSynthetic.cpp | 4 +- source/DataFormatters/ValueObjectPrinter.cpp | 10 +- source/Expression/ASTResultSynthesizer.cpp | 218 +- source/Expression/ASTStructExtractor.cpp | 64 +- source/Expression/ClangASTSource.cpp | 1010 ++--- source/Expression/ClangExpressionDeclMap.cpp | 866 ++-- source/Expression/ClangExpressionParser.cpp | 390 +- source/Expression/ClangExpressionVariable.cpp | 19 +- source/Expression/ClangFunction.cpp | 88 +- source/Expression/ClangUserExpression.cpp | 541 ++- source/Expression/ClangUtilityFunction.cpp | 37 +- source/Expression/DWARFExpression.cpp | 243 +- source/Expression/ExpressionSourceCode.cpp | 55 +- source/Expression/IRDynamicChecks.cpp | 213 +- source/Expression/IRExecutionUnit.cpp | 497 ++- source/Expression/IRForTarget.cpp | 1437 +++--- source/Expression/IRInterpreter.cpp | 519 ++- source/Expression/IRMemoryMap.cpp | 274 +- source/Expression/Materializer.cpp | 96 +- source/Host/common/Condition.cpp | 5 - source/Host/common/DynamicLibrary.cpp | 33 - source/Host/common/Editline.cpp | 418 +- source/Host/common/File.cpp | 39 +- source/Host/common/FileCache.cpp | 127 + source/Host/common/FileSpec.cpp | 381 +- source/Host/common/Host.cpp | 1516 +------ source/Host/common/HostInfoBase.cpp | 318 ++ source/Host/common/IOObject.cpp | 14 + source/Host/common/Mutex.cpp | 4 +- source/Host/common/NativeBreakpoint.cpp | 116 + source/Host/common/NativeBreakpoint.h | 66 + source/Host/common/NativeBreakpointList.cpp | 199 + source/Host/common/NativeBreakpointList.h | 53 + source/Host/common/NativeProcessProtocol.cpp | 412 ++ source/Host/common/NativeProcessProtocol.h | 333 ++ source/Host/common/NativeThreadProtocol.cpp | 97 + source/Host/common/NativeThreadProtocol.h | 85 + source/Host/common/OptionParser.cpp | 21 +- source/Host/common/Pipe.cpp | 171 + source/Host/common/Socket.cpp | 662 +++ source/Host/common/SocketAddress.cpp | 3 +- source/Host/common/SoftwareBreakpoint.cpp | 296 ++ source/Host/common/SoftwareBreakpoint.h | 51 + source/Host/common/Terminal.cpp | 5 +- source/Host/freebsd/Host.cpp | 102 +- source/Host/freebsd/HostInfoFreeBSD.cpp | 85 + source/Host/posix/FileSystem.cpp | 201 + source/Host/posix/HostInfoPosix.cpp | 193 + source/Host/posix/HostProcessPosix.cpp | 103 + source/Interpreter/Args.cpp | 125 +- source/Interpreter/CommandHistory.cpp | 20 +- source/Interpreter/CommandInterpreter.cpp | 195 +- source/Interpreter/CommandObject.cpp | 213 +- source/Interpreter/CommandObjectRegexCommand.cpp | 6 +- source/Interpreter/CommandObjectScript.cpp | 4 +- source/Interpreter/CommandOptionValidators.cpp | 39 + source/Interpreter/CommandReturnObject.cpp | 20 +- source/Interpreter/OptionGroupArchitecture.cpp | 2 +- source/Interpreter/OptionGroupBoolean.cpp | 3 +- source/Interpreter/OptionGroupFile.cpp | 6 +- source/Interpreter/OptionGroupFormat.cpp | 10 +- source/Interpreter/OptionGroupOutputFile.cpp | 10 +- source/Interpreter/OptionGroupPlatform.cpp | 8 +- source/Interpreter/OptionGroupString.cpp | 3 +- source/Interpreter/OptionGroupUInt64.cpp | 3 +- source/Interpreter/OptionGroupUUID.cpp | 2 +- .../Interpreter/OptionGroupValueObjectDisplay.cpp | 26 +- source/Interpreter/OptionGroupVariable.cpp | 16 +- source/Interpreter/OptionGroupWatchpoint.cpp | 8 +- source/Interpreter/OptionValue.cpp | 68 +- source/Interpreter/OptionValueArch.cpp | 2 +- source/Interpreter/OptionValueArray.cpp | 7 +- source/Interpreter/OptionValueBoolean.cpp | 5 +- source/Interpreter/OptionValueDictionary.cpp | 14 +- source/Interpreter/OptionValueEnumeration.cpp | 2 +- source/Interpreter/OptionValueFileSpec.cpp | 3 +- source/Interpreter/OptionValueFormat.cpp | 2 +- source/Interpreter/OptionValueProperties.cpp | 37 +- source/Interpreter/OptionValueUUID.cpp | 2 +- source/Interpreter/Options.cpp | 77 +- source/Interpreter/Property.cpp | 4 +- source/Interpreter/PythonDataObjects.cpp | 24 +- source/Interpreter/ScriptInterpreter.cpp | 35 +- source/Interpreter/ScriptInterpreterPython.cpp | 378 +- source/Interpreter/embedded_interpreter.py | 4 + source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp | 13 +- .../Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp | 1103 +++++ source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h | 145 + source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp | 10 +- .../Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp | 554 +++ source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h | 148 + source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp | 29 +- .../Disassembler/llvm/DisassemblerLLVMC.cpp | 140 +- .../Plugins/Disassembler/llvm/DisassemblerLLVMC.h | 46 +- .../Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp | 727 +++ .../Hexagon-DYLD/DynamicLoaderHexagonDYLD.h | 182 + .../Hexagon-DYLD/HexagonDYLDRendezvous.cpp | 403 ++ .../Hexagon-DYLD/HexagonDYLDRendezvous.h | 279 ++ .../Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp | 9 +- .../DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp | 60 +- .../POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp | 2 +- .../DynamicLoader/Static/DynamicLoaderStatic.h | 1 - .../Instruction/ARM/EmulateInstructionARM.cpp | 31 +- .../Instruction/ARM/EmulateInstructionARM.h | 2 +- .../Instruction/ARM64/EmulateInstructionARM64.cpp | 719 +++ .../Instruction/ARM64/EmulateInstructionARM64.h | 297 ++ source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp | 430 ++ source/Plugins/JITLoader/GDB/JITLoaderGDB.h | 104 + .../ItaniumABI/ItaniumABILanguageRuntime.cpp | 6 +- .../BSD-Archive/ObjectContainerBSDArchive.cpp | 35 +- source/Plugins/ObjectFile/ELF/ELFHeader.cpp | 6 + source/Plugins/ObjectFile/ELF/ELFHeader.h | 8 +- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 838 +++- source/Plugins/ObjectFile/ELF/ObjectFileELF.h | 55 +- source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp | 363 ++ source/Plugins/ObjectFile/JIT/ObjectFileJIT.h | 142 + .../Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp | 66 +- source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h | 2 +- source/Plugins/Platform/POSIX/PlatformPOSIX.cpp | 216 +- source/Plugins/Platform/POSIX/PlatformPOSIX.h | 41 +- .../gdb-server/PlatformRemoteGDBServer.cpp | 33 +- source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp | 27 +- source/Plugins/Process/FreeBSD/ProcessMonitor.cpp | 17 +- source/Plugins/Process/FreeBSD/ProcessMonitor.h | 7 +- source/Plugins/Process/POSIX/POSIXThread.cpp | 120 +- source/Plugins/Process/POSIX/ProcessPOSIX.cpp | 66 +- source/Plugins/Process/POSIX/ProcessPOSIX.h | 19 +- .../Process/POSIX/RegisterContextFreeBSD_i386.cpp | 88 - .../Process/POSIX/RegisterContextFreeBSD_i386.h | 29 - .../POSIX/RegisterContextFreeBSD_mips64.cpp | 90 - .../Process/POSIX/RegisterContextFreeBSD_mips64.h | 29 - .../POSIX/RegisterContextFreeBSD_x86_64.cpp | 126 - .../Process/POSIX/RegisterContextFreeBSD_x86_64.h | 29 - .../Process/POSIX/RegisterContextLinux_i386.cpp | 96 - .../Process/POSIX/RegisterContextLinux_i386.h | 29 - .../Process/POSIX/RegisterContextLinux_x86_64.cpp | 139 - .../Process/POSIX/RegisterContextLinux_x86_64.h | 29 - .../Plugins/Process/POSIX/RegisterContextPOSIX.h | 98 - .../RegisterContextPOSIXProcessMonitor_arm64.cpp | 318 ++ .../RegisterContextPOSIXProcessMonitor_arm64.h | 95 + .../RegisterContextPOSIXProcessMonitor_mips64.cpp | 3 +- .../RegisterContextPOSIXProcessMonitor_mips64.h | 4 +- .../RegisterContextPOSIXProcessMonitor_x86.cpp | 12 +- .../POSIX/RegisterContextPOSIXProcessMonitor_x86.h | 4 +- .../Process/POSIX/RegisterContextPOSIX_mips64.cpp | 238 - .../Process/POSIX/RegisterContextPOSIX_mips64.h | 138 - .../Process/POSIX/RegisterContextPOSIX_x86.cpp | 666 --- .../Process/POSIX/RegisterContextPOSIX_x86.h | 462 -- .../Plugins/Process/POSIX/RegisterContext_mips64.h | 104 - source/Plugins/Process/POSIX/RegisterContext_x86.h | 479 -- source/Plugins/Process/POSIX/RegisterInfos_i386.h | 207 - .../Plugins/Process/POSIX/RegisterInfos_mips64.h | 74 - .../Plugins/Process/POSIX/RegisterInfos_x86_64.h | 409 -- source/Plugins/Process/Utility/ARMDefines.h | 2 +- source/Plugins/Process/Utility/ARMUtils.h | 2 +- .../Process/Utility/DynamicRegisterInfo.cpp | 18 +- source/Plugins/Process/Utility/FreeBSDSignals.cpp | 31 + source/Plugins/Process/Utility/FreeBSDSignals.h | 28 + source/Plugins/Process/Utility/HistoryThread.cpp | 14 +- source/Plugins/Process/Utility/HistoryUnwind.cpp | 6 +- .../Plugins/Process/Utility/InferiorCallPOSIX.cpp | 12 +- source/Plugins/Process/Utility/InstructionUtils.h | 2 + source/Plugins/Process/Utility/LinuxSignals.cpp | 62 + source/Plugins/Process/Utility/LinuxSignals.h | 35 + .../Process/Utility/RegisterContextDarwin_arm.cpp | 16 +- .../Process/Utility/RegisterContextDarwin_arm.h | 2 +- .../Utility/RegisterContextDarwin_arm64.cpp | 944 ++++ .../Process/Utility/RegisterContextDarwin_arm64.h | 296 ++ .../Process/Utility/RegisterContextDarwin_i386.cpp | 13 +- .../Process/Utility/RegisterContextDarwin_i386.h | 2 +- .../Utility/RegisterContextDarwin_x86_64.cpp | 14 +- .../Process/Utility/RegisterContextDarwin_x86_64.h | 2 +- .../Process/Utility/RegisterContextDummy.cpp | 2 +- .../Plugins/Process/Utility/RegisterContextDummy.h | 2 +- .../Utility/RegisterContextFreeBSD_i386.cpp | 88 + .../Process/Utility/RegisterContextFreeBSD_i386.h | 31 + .../Utility/RegisterContextFreeBSD_mips64.cpp | 93 + .../Utility/RegisterContextFreeBSD_mips64.h | 31 + .../Utility/RegisterContextFreeBSD_x86_64.cpp | 159 + .../Utility/RegisterContextFreeBSD_x86_64.h | 35 + .../Process/Utility/RegisterContextHistory.cpp | 2 +- .../Process/Utility/RegisterContextHistory.h | 2 +- .../Process/Utility/RegisterContextLLDB.cpp | 49 +- .../Plugins/Process/Utility/RegisterContextLLDB.h | 4 +- .../Process/Utility/RegisterContextLinux_arm64.cpp | 89 + .../Process/Utility/RegisterContextLinux_arm64.h | 81 + .../Process/Utility/RegisterContextLinux_i386.cpp | 127 + .../Process/Utility/RegisterContextLinux_i386.h | 31 + .../Utility/RegisterContextLinux_x86_64.cpp | 171 + .../Process/Utility/RegisterContextLinux_x86_64.h | 35 + .../RegisterContextMacOSXFrameBackchain.cpp | 4 +- .../Utility/RegisterContextMacOSXFrameBackchain.h | 2 +- .../Process/Utility/RegisterContextMemory.cpp | 2 +- .../Process/Utility/RegisterContextMemory.h | 2 +- .../Plugins/Process/Utility/RegisterContextPOSIX.h | 79 + .../Process/Utility/RegisterContextPOSIX_arm64.cpp | 299 ++ .../Process/Utility/RegisterContextPOSIX_arm64.h | 272 ++ .../Utility/RegisterContextPOSIX_mips64.cpp | 237 + .../Process/Utility/RegisterContextPOSIX_mips64.h | 138 + .../Process/Utility/RegisterContextPOSIX_x86.cpp | 667 +++ .../Process/Utility/RegisterContextPOSIX_x86.h | 462 ++ .../Utility/RegisterContextThreadMemory.cpp | 2 +- .../Process/Utility/RegisterContextThreadMemory.h | 2 +- .../Process/Utility/RegisterContext_mips64.h | 104 + .../Plugins/Process/Utility/RegisterContext_x86.h | 487 ++ .../Process/Utility/RegisterInfoInterface.h | 49 + .../Plugins/Process/Utility/RegisterInfos_arm64.h | 347 ++ .../Plugins/Process/Utility/RegisterInfos_i386.h | 211 + .../Plugins/Process/Utility/RegisterInfos_mips64.h | 76 + .../Plugins/Process/Utility/RegisterInfos_x86_64.h | 411 ++ .../Process/Utility/StopInfoMachException.cpp | 68 +- source/Plugins/Process/Utility/UnwindLLDB.cpp | 2 +- .../Process/Utility/lldb-x86-register-enums.h | 292 ++ source/Plugins/Process/elf-core/ProcessElfCore.cpp | 71 +- source/Plugins/Process/elf-core/ProcessElfCore.h | 48 +- .../elf-core/RegisterContextPOSIXCore_mips64.cpp | 22 +- .../elf-core/RegisterContextPOSIXCore_mips64.h | 8 +- .../elf-core/RegisterContextPOSIXCore_x86_64.h | 4 +- source/Plugins/Process/elf-core/ThreadElfCore.cpp | 6 +- source/Plugins/Process/elf-core/ThreadElfCore.h | 2 +- .../Process/gdb-remote/GDBRemoteCommunication.cpp | 175 +- .../Process/gdb-remote/GDBRemoteCommunication.h | 2 +- .../gdb-remote/GDBRemoteCommunicationClient.cpp | 386 +- .../gdb-remote/GDBRemoteCommunicationClient.h | 53 +- .../gdb-remote/GDBRemoteCommunicationServer.cpp | 4703 +++++++++++++++----- .../gdb-remote/GDBRemoteCommunicationServer.h | 210 +- .../gdb-remote/GDBRemoteRegisterContext.cpp | 328 +- .../Process/gdb-remote/GDBRemoteRegisterContext.h | 2 +- .../Process/gdb-remote/ProcessGDBRemote.cpp | 397 +- .../Plugins/Process/gdb-remote/ProcessGDBRemote.h | 25 +- .../Plugins/Process/gdb-remote/ThreadGDBRemote.cpp | 52 + .../Plugins/Process/gdb-remote/ThreadGDBRemote.h | 10 + .../DWARF/DWARFAbbreviationDeclaration.cpp | 94 - .../DWARF/DWARFAbbreviationDeclaration.h | 9 - .../Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp | 53 +- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h | 3 +- .../SymbolFile/DWARF/DWARFDebugArangeSet.cpp | 94 +- .../Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp | 5 +- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp | 55 +- .../SymbolFile/DWARF/DWARFDebugInfoEntry.cpp | 34 + .../Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h | 10 +- source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp | 16 +- .../SymbolFile/DWARF/DWARFDebugPubnames.cpp | 5 +- .../Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp | 2 +- .../Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp | 2 +- source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp | 2 +- source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h | 16 +- .../Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp | 4 +- .../Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 528 ++- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h | 9 +- .../SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp | 41 +- .../SymbolFile/DWARF/SymbolFileDWARFDebugMap.h | 4 +- .../Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp | 16 +- .../InstEmulation/UnwindAssemblyInstEmulation.cpp | 17 +- .../InstEmulation/UnwindAssemblyInstEmulation.h | 5 + .../UnwindAssembly/x86/UnwindAssembly-x86.cpp | 475 +- .../UnwindAssembly/x86/UnwindAssembly-x86.h | 5 + source/Symbol/Block.cpp | 46 +- source/Symbol/ClangASTContext.cpp | 438 +- source/Symbol/ClangASTImporter.cpp | 178 +- source/Symbol/ClangASTType.cpp | 2158 +++++---- source/Symbol/ClangExternalASTSourceCallbacks.cpp | 2 +- source/Symbol/ClangExternalASTSourceCommon.cpp | 2 +- source/Symbol/CompileUnit.cpp | 16 +- source/Symbol/DWARFCallFrameInfo.cpp | 62 +- source/Symbol/FuncUnwinders.cpp | 61 +- source/Symbol/Function.cpp | 46 +- source/Symbol/LineTable.cpp | 30 +- source/Symbol/ObjectFile.cpp | 115 +- source/Symbol/Symbol.cpp | 144 +- source/Symbol/SymbolContext.cpp | 108 +- source/Symbol/SymbolFile.cpp | 6 +- source/Symbol/SymbolVendor.cpp | 33 +- source/Symbol/Symtab.cpp | 80 +- source/Symbol/Type.cpp | 313 +- source/Symbol/TypeList.cpp | 43 - source/Symbol/UnwindPlan.cpp | 25 +- source/Symbol/UnwindTable.cpp | 34 +- source/Symbol/Variable.cpp | 26 +- source/Target/ABI.cpp | 34 +- source/Target/FileAction.cpp | 95 + source/Target/JITLoader.cpp | 38 + source/Target/JITLoaderList.cpp | 77 + source/Target/LanguageRuntime.cpp | 12 + source/Target/Memory.cpp | 36 +- source/Target/NativeRegisterContext.cpp | 470 ++ .../Target/NativeRegisterContextRegisterInfo.cpp | 44 + source/Target/ObjCLanguageRuntime.cpp | 23 + source/Target/PathMappingList.cpp | 4 +- source/Target/Platform.cpp | 103 +- source/Target/Process.cpp | 1458 +++--- source/Target/ProcessInfo.cpp | 138 + source/Target/ProcessLaunchInfo.cpp | 459 ++ source/Target/Queue.cpp | 15 +- source/Target/QueueItem.cpp | 85 +- source/Target/RegisterContext.cpp | 4 +- source/Target/SectionLoadHistory.cpp | 19 +- source/Target/SectionLoadList.cpp | 31 +- source/Target/StackFrame.cpp | 15 +- source/Target/StackFrameList.cpp | 4 +- source/Target/StackID.cpp | 5 +- source/Target/StopInfo.cpp | 106 +- source/Target/Target.cpp | 127 +- source/Target/TargetList.cpp | 183 +- source/Target/Thread.cpp | 335 +- source/Target/ThreadList.cpp | 11 +- source/Target/ThreadPlan.cpp | 15 +- source/Target/ThreadPlanBase.cpp | 4 +- source/Target/ThreadPlanCallFunction.cpp | 97 +- source/Target/ThreadPlanCallUserExpression.cpp | 52 +- source/Target/ThreadPlanRunToAddress.cpp | 2 +- source/Target/ThreadPlanShouldStopHere.cpp | 142 +- source/Target/ThreadPlanStepInRange.cpp | 132 +- source/Target/ThreadPlanStepInstruction.cpp | 94 +- source/Target/ThreadPlanStepOut.cpp | 179 +- source/Target/ThreadPlanStepOverRange.cpp | 58 +- source/Target/ThreadPlanStepRange.cpp | 19 +- source/Target/ThreadPlanStepUntil.cpp | 2 +- source/Target/ThreadPlanTracer.cpp | 11 - source/Utility/ARM64_DWARF_Registers.cpp | 148 + source/Utility/ARM64_DWARF_Registers.h | 102 + source/Utility/ARM64_GCC_Registers.h | 92 + source/Utility/ARM_DWARF_Registers.cpp | 2 +- source/Utility/PseudoTerminal.cpp | 9 +- source/Utility/SharingPtr.cpp | 4 +- source/Utility/StringExtractor.cpp | 31 +- source/Utility/StringExtractor.h | 5 +- source/Utility/StringExtractorGDBRemote.cpp | 6 + source/Utility/StringExtractorGDBRemote.h | 3 + source/Utility/StringLexer.cpp | 101 + source/Utility/TimeSpecTimeout.h | 2 +- source/lldb-log.cpp | 5 +- source/lldb.cpp | 75 +- tools/driver/Driver.cpp | 242 +- tools/driver/Driver.h | 5 +- tools/driver/Platform.cpp | 25 +- tools/driver/Platform.h | 56 +- tools/lldb-mi/Driver.cpp | 1299 ++++++ tools/lldb-mi/Driver.h | 163 + tools/lldb-mi/MICmdArgContext.cpp | 255 ++ tools/lldb-mi/MICmdArgContext.h | 61 + tools/lldb-mi/MICmdArgSet.cpp | 420 ++ tools/lldb-mi/MICmdArgSet.h | 109 + tools/lldb-mi/MICmdArgValBase.cpp | 171 + tools/lldb-mi/MICmdArgValBase.h | 157 + tools/lldb-mi/MICmdArgValConsume.cpp | 119 + tools/lldb-mi/MICmdArgValConsume.h | 63 + tools/lldb-mi/MICmdArgValFile.cpp | 204 + tools/lldb-mi/MICmdArgValFile.h | 61 + tools/lldb-mi/MICmdArgValListBase.cpp | 221 + tools/lldb-mi/MICmdArgValListBase.h | 103 + tools/lldb-mi/MICmdArgValListOfN.cpp | 189 + tools/lldb-mi/MICmdArgValListOfN.h | 98 + tools/lldb-mi/MICmdArgValNumber.cpp | 167 + tools/lldb-mi/MICmdArgValNumber.h | 65 + tools/lldb-mi/MICmdArgValOptionLong.cpp | 319 ++ tools/lldb-mi/MICmdArgValOptionLong.h | 109 + tools/lldb-mi/MICmdArgValOptionShort.cpp | 128 + tools/lldb-mi/MICmdArgValOptionShort.h | 65 + tools/lldb-mi/MICmdArgValString.cpp | 502 +++ tools/lldb-mi/MICmdArgValString.h | 76 + tools/lldb-mi/MICmdArgValThreadGrp.cpp | 173 + tools/lldb-mi/MICmdArgValThreadGrp.h | 66 + tools/lldb-mi/MICmdBase.cpp | 263 ++ tools/lldb-mi/MICmdBase.h | 156 + tools/lldb-mi/MICmdCmd.cpp | 174 + tools/lldb-mi/MICmdCmd.h | 104 + tools/lldb-mi/MICmdCmdBreak.cpp | 1026 +++++ tools/lldb-mi/MICmdCmdBreak.h | 292 ++ tools/lldb-mi/MICmdCmdData.cpp | 1365 ++++++ tools/lldb-mi/MICmdCmdData.h | 374 ++ tools/lldb-mi/MICmdCmdEnviro.cpp | 143 + tools/lldb-mi/MICmdCmdEnviro.h | 69 + tools/lldb-mi/MICmdCmdExec.cpp | 982 ++++ tools/lldb-mi/MICmdCmdExec.h | 310 ++ tools/lldb-mi/MICmdCmdFile.cpp | 184 + tools/lldb-mi/MICmdCmdFile.h | 71 + tools/lldb-mi/MICmdCmdGdbInfo.cpp | 232 + tools/lldb-mi/MICmdCmdGdbInfo.h | 93 + tools/lldb-mi/MICmdCmdGdbSet.cpp | 260 ++ tools/lldb-mi/MICmdCmdGdbSet.h | 96 + tools/lldb-mi/MICmdCmdGdbThread.cpp | 100 + tools/lldb-mi/MICmdCmdGdbThread.h | 61 + tools/lldb-mi/MICmdCmdMiscellanous.cpp | 588 +++ tools/lldb-mi/MICmdCmdMiscellanous.h | 175 + tools/lldb-mi/MICmdCmdStack.cpp | 634 +++ tools/lldb-mi/MICmdCmdStack.h | 184 + tools/lldb-mi/MICmdCmdSupportInfo.cpp | 129 + tools/lldb-mi/MICmdCmdSupportInfo.h | 69 + tools/lldb-mi/MICmdCmdSupportList.cpp | 102 + tools/lldb-mi/MICmdCmdSupportList.h | 63 + tools/lldb-mi/MICmdCmdTarget.cpp | 217 + tools/lldb-mi/MICmdCmdTarget.h | 70 + tools/lldb-mi/MICmdCmdThread.cpp | 207 + tools/lldb-mi/MICmdCmdThread.h | 76 + tools/lldb-mi/MICmdCmdTrace.cpp | 99 + tools/lldb-mi/MICmdCmdTrace.h | 61 + tools/lldb-mi/MICmdCmdVar.cpp | 1492 +++++++ tools/lldb-mi/MICmdCmdVar.h | 382 ++ tools/lldb-mi/MICmdCommands.cpp | 135 + tools/lldb-mi/MICmdCommands.h | 36 + tools/lldb-mi/MICmdData.cpp | 24 + tools/lldb-mi/MICmdData.h | 74 + tools/lldb-mi/MICmdFactory.cpp | 229 + tools/lldb-mi/MICmdFactory.h | 99 + tools/lldb-mi/MICmdInterpreter.cpp | 301 ++ tools/lldb-mi/MICmdInterpreter.h | 78 + tools/lldb-mi/MICmdInvoker.cpp | 333 ++ tools/lldb-mi/MICmdInvoker.h | 118 + tools/lldb-mi/MICmdMgr.cpp | 257 ++ tools/lldb-mi/MICmdMgr.h | 83 + tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.cpp | 110 + tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h | 88 + tools/lldb-mi/MICmnBase.cpp | 144 + tools/lldb-mi/MICmnBase.h | 60 + tools/lldb-mi/MICmnConfig.h | 50 + tools/lldb-mi/MICmnLLDBBroadcaster.cpp | 89 + tools/lldb-mi/MICmnLLDBBroadcaster.h | 61 + tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp | 1312 ++++++ tools/lldb-mi/MICmnLLDBDebugSessionInfo.h | 236 + tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp | 570 +++ tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h | 139 + tools/lldb-mi/MICmnLLDBDebugger.cpp | 707 +++ tools/lldb-mi/MICmnLLDBDebugger.h | 125 + tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp | 1566 +++++++ tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h | 97 + tools/lldb-mi/MICmnLLDBProxySBValue.cpp | 153 + tools/lldb-mi/MICmnLLDBProxySBValue.h | 47 + tools/lldb-mi/MICmnLLDBUtilSBValue.cpp | 324 ++ tools/lldb-mi/MICmnLLDBUtilSBValue.h | 71 + tools/lldb-mi/MICmnLog.cpp | 355 ++ tools/lldb-mi/MICmnLog.h | 143 + tools/lldb-mi/MICmnLogMediumFile.cpp | 420 ++ tools/lldb-mi/MICmnLogMediumFile.h | 96 + tools/lldb-mi/MICmnMIOutOfBandRecord.cpp | 161 + tools/lldb-mi/MICmnMIOutOfBandRecord.h | 110 + tools/lldb-mi/MICmnMIResultRecord.cpp | 142 + tools/lldb-mi/MICmnMIResultRecord.h | 106 + tools/lldb-mi/MICmnMIValue.cpp | 64 + tools/lldb-mi/MICmnMIValue.h | 64 + tools/lldb-mi/MICmnMIValueConst.cpp | 98 + tools/lldb-mi/MICmnMIValueConst.h | 72 + tools/lldb-mi/MICmnMIValueList.cpp | 203 + tools/lldb-mi/MICmnMIValueList.h | 70 + tools/lldb-mi/MICmnMIValueResult.cpp | 141 + tools/lldb-mi/MICmnMIValueResult.h | 75 + tools/lldb-mi/MICmnMIValueTuple.cpp | 227 + tools/lldb-mi/MICmnMIValueTuple.h | 76 + tools/lldb-mi/MICmnResources.cpp | 409 ++ tools/lldb-mi/MICmnResources.h | 351 ++ tools/lldb-mi/MICmnStreamStderr.cpp | 257 ++ tools/lldb-mi/MICmnStreamStderr.h | 76 + tools/lldb-mi/MICmnStreamStdin.cpp | 421 ++ tools/lldb-mi/MICmnStreamStdin.h | 125 + tools/lldb-mi/MICmnStreamStdinLinux.cpp | 212 + tools/lldb-mi/MICmnStreamStdinLinux.h | 75 + tools/lldb-mi/MICmnStreamStdinWindows.cpp | 279 ++ tools/lldb-mi/MICmnStreamStdinWindows.h | 81 + tools/lldb-mi/MICmnStreamStdout.cpp | 230 + tools/lldb-mi/MICmnStreamStdout.h | 75 + tools/lldb-mi/MICmnThreadMgrStd.cpp | 167 + tools/lldb-mi/MICmnThreadMgrStd.h | 134 + tools/lldb-mi/MIDataTypes.h | 100 + tools/lldb-mi/MIDriver.cpp | 1276 ++++++ tools/lldb-mi/MIDriver.h | 182 + tools/lldb-mi/MIDriverBase.cpp | 195 + tools/lldb-mi/MIDriverBase.h | 78 + tools/lldb-mi/MIDriverMain.cpp | 393 ++ tools/lldb-mi/MIDriverMgr.cpp | 762 ++++ tools/lldb-mi/MIDriverMgr.h | 138 + tools/lldb-mi/MIReadMe.txt | 261 ++ tools/lldb-mi/MIUtilDateTimeStd.cpp | 84 + tools/lldb-mi/MIUtilDateTimeStd.h | 55 + tools/lldb-mi/MIUtilDebug.cpp | 128 + tools/lldb-mi/MIUtilDebug.h | 96 + tools/lldb-mi/MIUtilFileStd.cpp | 290 ++ tools/lldb-mi/MIUtilFileStd.h | 65 + tools/lldb-mi/MIUtilMapIdToVariant.cpp | 124 + tools/lldb-mi/MIUtilMapIdToVariant.h | 148 + tools/lldb-mi/MIUtilSingletonBase.h | 71 + tools/lldb-mi/MIUtilSingletonHelper.h | 95 + tools/lldb-mi/MIUtilString.cpp | 680 +++ tools/lldb-mi/MIUtilString.h | 85 + tools/lldb-mi/MIUtilSystemLinux.cpp | 119 + tools/lldb-mi/MIUtilSystemLinux.h | 57 + tools/lldb-mi/MIUtilSystemOsx.cpp | 125 + tools/lldb-mi/MIUtilSystemOsx.h | 57 + tools/lldb-mi/MIUtilSystemWindows.cpp | 151 + tools/lldb-mi/MIUtilSystemWindows.h | 56 + tools/lldb-mi/MIUtilTermios.cpp | 69 + tools/lldb-mi/MIUtilTermios.h | 30 + tools/lldb-mi/MIUtilThreadBaseStd.cpp | 339 ++ tools/lldb-mi/MIUtilThreadBaseStd.h | 170 + tools/lldb-mi/MIUtilVariant.cpp | 392 ++ tools/lldb-mi/MIUtilVariant.h | 288 ++ tools/lldb-mi/Platform.cpp | 109 + tools/lldb-mi/Platform.h | 109 + tools/lldb-platform/lldb-platform.cpp | 7 +- 817 files changed, 86652 insertions(+), 20891 deletions(-) create mode 100644 include/lldb/API/SBTypeEnumMember.h create mode 100644 include/lldb/API/SBUnixSignals.h create mode 100644 include/lldb/Core/StructuredData.h delete mode 100644 include/lldb/Host/DynamicLibrary.h create mode 100644 include/lldb/Host/FileCache.h create mode 100644 include/lldb/Host/FileSystem.h create mode 100644 include/lldb/Host/HostInfo.h create mode 100644 include/lldb/Host/HostInfoBase.h create mode 100644 include/lldb/Host/HostProcess.h create mode 100644 include/lldb/Host/IOObject.h create mode 100644 include/lldb/Host/Pipe.h create mode 100644 include/lldb/Host/Socket.h create mode 100644 include/lldb/Host/freebsd/HostInfoFreeBSD.h create mode 100644 include/lldb/Host/posix/HostInfoPosix.h create mode 100644 include/lldb/Host/posix/HostProcessPosix.h create mode 100644 include/lldb/Interpreter/CommandOptionValidators.h create mode 100644 include/lldb/Target/FileAction.h create mode 100644 include/lldb/Target/JITLoader.h create mode 100644 include/lldb/Target/JITLoaderList.h create mode 100644 include/lldb/Target/MemoryRegionInfo.h create mode 100644 include/lldb/Target/NativeRegisterContext.h create mode 100644 include/lldb/Target/NativeRegisterContextRegisterInfo.h create mode 100644 include/lldb/Target/ProcessInfo.h create mode 100644 include/lldb/Target/ProcessLaunchInfo.h create mode 100644 include/lldb/Utility/SafeMachO.h create mode 100644 include/lldb/Utility/StringLexer.h create mode 100644 include/lldb/lldb-private-forward.h create mode 100644 source/API/SBTypeEnumMember.cpp create mode 100644 source/API/SBUnixSignals.cpp create mode 100644 source/Core/FastDemangle.cpp create mode 100644 source/Core/StructuredData.cpp delete mode 100644 source/Host/common/DynamicLibrary.cpp create mode 100644 source/Host/common/FileCache.cpp create mode 100644 source/Host/common/HostInfoBase.cpp create mode 100644 source/Host/common/IOObject.cpp create mode 100644 source/Host/common/NativeBreakpoint.cpp create mode 100644 source/Host/common/NativeBreakpoint.h create mode 100644 source/Host/common/NativeBreakpointList.cpp create mode 100644 source/Host/common/NativeBreakpointList.h create mode 100644 source/Host/common/NativeProcessProtocol.cpp create mode 100644 source/Host/common/NativeProcessProtocol.h create mode 100644 source/Host/common/NativeThreadProtocol.cpp create mode 100644 source/Host/common/NativeThreadProtocol.h create mode 100644 source/Host/common/Pipe.cpp create mode 100644 source/Host/common/Socket.cpp create mode 100644 source/Host/common/SoftwareBreakpoint.cpp create mode 100644 source/Host/common/SoftwareBreakpoint.h create mode 100644 source/Host/freebsd/HostInfoFreeBSD.cpp create mode 100644 source/Host/posix/FileSystem.cpp create mode 100644 source/Host/posix/HostInfoPosix.cpp create mode 100644 source/Host/posix/HostProcessPosix.cpp create mode 100644 source/Interpreter/CommandOptionValidators.cpp create mode 100644 source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp create mode 100644 source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h create mode 100644 source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp create mode 100644 source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h create mode 100644 source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp create mode 100644 source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h create mode 100644 source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp create mode 100644 source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h create mode 100644 source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp create mode 100644 source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h create mode 100644 source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp create mode 100644 source/Plugins/JITLoader/GDB/JITLoaderGDB.h create mode 100644 source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp create mode 100644 source/Plugins/ObjectFile/JIT/ObjectFileJIT.h delete mode 100644 source/Plugins/Process/POSIX/RegisterContextFreeBSD_i386.cpp delete mode 100644 source/Plugins/Process/POSIX/RegisterContextFreeBSD_i386.h delete mode 100644 source/Plugins/Process/POSIX/RegisterContextFreeBSD_mips64.cpp delete mode 100644 source/Plugins/Process/POSIX/RegisterContextFreeBSD_mips64.h delete mode 100644 source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.cpp delete mode 100644 source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.h delete mode 100644 source/Plugins/Process/POSIX/RegisterContextLinux_i386.cpp delete mode 100644 source/Plugins/Process/POSIX/RegisterContextLinux_i386.h delete mode 100644 source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.cpp delete mode 100644 source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.h delete mode 100644 source/Plugins/Process/POSIX/RegisterContextPOSIX.h create mode 100644 source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm64.cpp create mode 100644 source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm64.h delete mode 100644 source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.cpp delete mode 100644 source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h delete mode 100644 source/Plugins/Process/POSIX/RegisterContextPOSIX_x86.cpp delete mode 100644 source/Plugins/Process/POSIX/RegisterContextPOSIX_x86.h delete mode 100644 source/Plugins/Process/POSIX/RegisterContext_mips64.h delete mode 100644 source/Plugins/Process/POSIX/RegisterContext_x86.h delete mode 100644 source/Plugins/Process/POSIX/RegisterInfos_i386.h delete mode 100644 source/Plugins/Process/POSIX/RegisterInfos_mips64.h delete mode 100644 source/Plugins/Process/POSIX/RegisterInfos_x86_64.h create mode 100644 source/Plugins/Process/Utility/FreeBSDSignals.cpp create mode 100644 source/Plugins/Process/Utility/FreeBSDSignals.h create mode 100644 source/Plugins/Process/Utility/LinuxSignals.cpp create mode 100644 source/Plugins/Process/Utility/LinuxSignals.h create mode 100644 source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp create mode 100644 source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h create mode 100644 source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp create mode 100644 source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.h create mode 100644 source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp create mode 100644 source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h create mode 100644 source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp create mode 100644 source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h create mode 100644 source/Plugins/Process/Utility/RegisterContextLinux_arm64.cpp create mode 100644 source/Plugins/Process/Utility/RegisterContextLinux_arm64.h create mode 100644 source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp create mode 100644 source/Plugins/Process/Utility/RegisterContextLinux_i386.h create mode 100644 source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp create mode 100644 source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h create mode 100644 source/Plugins/Process/Utility/RegisterContextPOSIX.h create mode 100644 source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp create mode 100644 source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h create mode 100644 source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp create mode 100644 source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h create mode 100644 source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp create mode 100644 source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h create mode 100644 source/Plugins/Process/Utility/RegisterContext_mips64.h create mode 100644 source/Plugins/Process/Utility/RegisterContext_x86.h create mode 100644 source/Plugins/Process/Utility/RegisterInfoInterface.h create mode 100644 source/Plugins/Process/Utility/RegisterInfos_arm64.h create mode 100644 source/Plugins/Process/Utility/RegisterInfos_i386.h create mode 100644 source/Plugins/Process/Utility/RegisterInfos_mips64.h create mode 100644 source/Plugins/Process/Utility/RegisterInfos_x86_64.h create mode 100644 source/Plugins/Process/Utility/lldb-x86-register-enums.h create mode 100644 source/Target/FileAction.cpp create mode 100644 source/Target/JITLoader.cpp create mode 100644 source/Target/JITLoaderList.cpp create mode 100644 source/Target/NativeRegisterContext.cpp create mode 100644 source/Target/NativeRegisterContextRegisterInfo.cpp create mode 100644 source/Target/ProcessInfo.cpp create mode 100644 source/Target/ProcessLaunchInfo.cpp create mode 100644 source/Utility/ARM64_DWARF_Registers.cpp create mode 100644 source/Utility/ARM64_DWARF_Registers.h create mode 100644 source/Utility/ARM64_GCC_Registers.h create mode 100644 source/Utility/StringLexer.cpp create mode 100644 tools/lldb-mi/Driver.cpp create mode 100644 tools/lldb-mi/Driver.h create mode 100644 tools/lldb-mi/MICmdArgContext.cpp create mode 100644 tools/lldb-mi/MICmdArgContext.h create mode 100644 tools/lldb-mi/MICmdArgSet.cpp create mode 100644 tools/lldb-mi/MICmdArgSet.h create mode 100644 tools/lldb-mi/MICmdArgValBase.cpp create mode 100644 tools/lldb-mi/MICmdArgValBase.h create mode 100644 tools/lldb-mi/MICmdArgValConsume.cpp create mode 100644 tools/lldb-mi/MICmdArgValConsume.h create mode 100644 tools/lldb-mi/MICmdArgValFile.cpp create mode 100644 tools/lldb-mi/MICmdArgValFile.h create mode 100644 tools/lldb-mi/MICmdArgValListBase.cpp create mode 100644 tools/lldb-mi/MICmdArgValListBase.h create mode 100644 tools/lldb-mi/MICmdArgValListOfN.cpp create mode 100644 tools/lldb-mi/MICmdArgValListOfN.h create mode 100644 tools/lldb-mi/MICmdArgValNumber.cpp create mode 100644 tools/lldb-mi/MICmdArgValNumber.h create mode 100644 tools/lldb-mi/MICmdArgValOptionLong.cpp create mode 100644 tools/lldb-mi/MICmdArgValOptionLong.h create mode 100644 tools/lldb-mi/MICmdArgValOptionShort.cpp create mode 100644 tools/lldb-mi/MICmdArgValOptionShort.h create mode 100644 tools/lldb-mi/MICmdArgValString.cpp create mode 100644 tools/lldb-mi/MICmdArgValString.h create mode 100644 tools/lldb-mi/MICmdArgValThreadGrp.cpp create mode 100644 tools/lldb-mi/MICmdArgValThreadGrp.h create mode 100644 tools/lldb-mi/MICmdBase.cpp create mode 100644 tools/lldb-mi/MICmdBase.h create mode 100644 tools/lldb-mi/MICmdCmd.cpp create mode 100644 tools/lldb-mi/MICmdCmd.h create mode 100644 tools/lldb-mi/MICmdCmdBreak.cpp create mode 100644 tools/lldb-mi/MICmdCmdBreak.h create mode 100644 tools/lldb-mi/MICmdCmdData.cpp create mode 100644 tools/lldb-mi/MICmdCmdData.h create mode 100644 tools/lldb-mi/MICmdCmdEnviro.cpp create mode 100644 tools/lldb-mi/MICmdCmdEnviro.h create mode 100644 tools/lldb-mi/MICmdCmdExec.cpp create mode 100644 tools/lldb-mi/MICmdCmdExec.h create mode 100644 tools/lldb-mi/MICmdCmdFile.cpp create mode 100644 tools/lldb-mi/MICmdCmdFile.h create mode 100644 tools/lldb-mi/MICmdCmdGdbInfo.cpp create mode 100644 tools/lldb-mi/MICmdCmdGdbInfo.h create mode 100644 tools/lldb-mi/MICmdCmdGdbSet.cpp create mode 100644 tools/lldb-mi/MICmdCmdGdbSet.h create mode 100644 tools/lldb-mi/MICmdCmdGdbThread.cpp create mode 100644 tools/lldb-mi/MICmdCmdGdbThread.h create mode 100644 tools/lldb-mi/MICmdCmdMiscellanous.cpp create mode 100644 tools/lldb-mi/MICmdCmdMiscellanous.h create mode 100644 tools/lldb-mi/MICmdCmdStack.cpp create mode 100644 tools/lldb-mi/MICmdCmdStack.h create mode 100644 tools/lldb-mi/MICmdCmdSupportInfo.cpp create mode 100644 tools/lldb-mi/MICmdCmdSupportInfo.h create mode 100644 tools/lldb-mi/MICmdCmdSupportList.cpp create mode 100644 tools/lldb-mi/MICmdCmdSupportList.h create mode 100644 tools/lldb-mi/MICmdCmdTarget.cpp create mode 100644 tools/lldb-mi/MICmdCmdTarget.h create mode 100644 tools/lldb-mi/MICmdCmdThread.cpp create mode 100644 tools/lldb-mi/MICmdCmdThread.h create mode 100644 tools/lldb-mi/MICmdCmdTrace.cpp create mode 100644 tools/lldb-mi/MICmdCmdTrace.h create mode 100644 tools/lldb-mi/MICmdCmdVar.cpp create mode 100644 tools/lldb-mi/MICmdCmdVar.h create mode 100644 tools/lldb-mi/MICmdCommands.cpp create mode 100644 tools/lldb-mi/MICmdCommands.h create mode 100644 tools/lldb-mi/MICmdData.cpp create mode 100644 tools/lldb-mi/MICmdData.h create mode 100644 tools/lldb-mi/MICmdFactory.cpp create mode 100644 tools/lldb-mi/MICmdFactory.h create mode 100644 tools/lldb-mi/MICmdInterpreter.cpp create mode 100644 tools/lldb-mi/MICmdInterpreter.h create mode 100644 tools/lldb-mi/MICmdInvoker.cpp create mode 100644 tools/lldb-mi/MICmdInvoker.h create mode 100644 tools/lldb-mi/MICmdMgr.cpp create mode 100644 tools/lldb-mi/MICmdMgr.h create mode 100644 tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.cpp create mode 100644 tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h create mode 100644 tools/lldb-mi/MICmnBase.cpp create mode 100644 tools/lldb-mi/MICmnBase.h create mode 100644 tools/lldb-mi/MICmnConfig.h create mode 100644 tools/lldb-mi/MICmnLLDBBroadcaster.cpp create mode 100644 tools/lldb-mi/MICmnLLDBBroadcaster.h create mode 100644 tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp create mode 100644 tools/lldb-mi/MICmnLLDBDebugSessionInfo.h create mode 100644 tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp create mode 100644 tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h create mode 100644 tools/lldb-mi/MICmnLLDBDebugger.cpp create mode 100644 tools/lldb-mi/MICmnLLDBDebugger.h create mode 100644 tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp create mode 100644 tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h create mode 100644 tools/lldb-mi/MICmnLLDBProxySBValue.cpp create mode 100644 tools/lldb-mi/MICmnLLDBProxySBValue.h create mode 100644 tools/lldb-mi/MICmnLLDBUtilSBValue.cpp create mode 100644 tools/lldb-mi/MICmnLLDBUtilSBValue.h create mode 100644 tools/lldb-mi/MICmnLog.cpp create mode 100644 tools/lldb-mi/MICmnLog.h create mode 100644 tools/lldb-mi/MICmnLogMediumFile.cpp create mode 100644 tools/lldb-mi/MICmnLogMediumFile.h create mode 100644 tools/lldb-mi/MICmnMIOutOfBandRecord.cpp create mode 100644 tools/lldb-mi/MICmnMIOutOfBandRecord.h create mode 100644 tools/lldb-mi/MICmnMIResultRecord.cpp create mode 100644 tools/lldb-mi/MICmnMIResultRecord.h create mode 100644 tools/lldb-mi/MICmnMIValue.cpp create mode 100644 tools/lldb-mi/MICmnMIValue.h create mode 100644 tools/lldb-mi/MICmnMIValueConst.cpp create mode 100644 tools/lldb-mi/MICmnMIValueConst.h create mode 100644 tools/lldb-mi/MICmnMIValueList.cpp create mode 100644 tools/lldb-mi/MICmnMIValueList.h create mode 100644 tools/lldb-mi/MICmnMIValueResult.cpp create mode 100644 tools/lldb-mi/MICmnMIValueResult.h create mode 100644 tools/lldb-mi/MICmnMIValueTuple.cpp create mode 100644 tools/lldb-mi/MICmnMIValueTuple.h create mode 100644 tools/lldb-mi/MICmnResources.cpp create mode 100644 tools/lldb-mi/MICmnResources.h create mode 100644 tools/lldb-mi/MICmnStreamStderr.cpp create mode 100644 tools/lldb-mi/MICmnStreamStderr.h create mode 100644 tools/lldb-mi/MICmnStreamStdin.cpp create mode 100644 tools/lldb-mi/MICmnStreamStdin.h create mode 100644 tools/lldb-mi/MICmnStreamStdinLinux.cpp create mode 100644 tools/lldb-mi/MICmnStreamStdinLinux.h create mode 100644 tools/lldb-mi/MICmnStreamStdinWindows.cpp create mode 100644 tools/lldb-mi/MICmnStreamStdinWindows.h create mode 100644 tools/lldb-mi/MICmnStreamStdout.cpp create mode 100644 tools/lldb-mi/MICmnStreamStdout.h create mode 100644 tools/lldb-mi/MICmnThreadMgrStd.cpp create mode 100644 tools/lldb-mi/MICmnThreadMgrStd.h create mode 100644 tools/lldb-mi/MIDataTypes.h create mode 100644 tools/lldb-mi/MIDriver.cpp create mode 100644 tools/lldb-mi/MIDriver.h create mode 100644 tools/lldb-mi/MIDriverBase.cpp create mode 100644 tools/lldb-mi/MIDriverBase.h create mode 100644 tools/lldb-mi/MIDriverMain.cpp create mode 100644 tools/lldb-mi/MIDriverMgr.cpp create mode 100644 tools/lldb-mi/MIDriverMgr.h create mode 100644 tools/lldb-mi/MIReadMe.txt create mode 100644 tools/lldb-mi/MIUtilDateTimeStd.cpp create mode 100644 tools/lldb-mi/MIUtilDateTimeStd.h create mode 100644 tools/lldb-mi/MIUtilDebug.cpp create mode 100644 tools/lldb-mi/MIUtilDebug.h create mode 100644 tools/lldb-mi/MIUtilFileStd.cpp create mode 100644 tools/lldb-mi/MIUtilFileStd.h create mode 100644 tools/lldb-mi/MIUtilMapIdToVariant.cpp create mode 100644 tools/lldb-mi/MIUtilMapIdToVariant.h create mode 100644 tools/lldb-mi/MIUtilSingletonBase.h create mode 100644 tools/lldb-mi/MIUtilSingletonHelper.h create mode 100644 tools/lldb-mi/MIUtilString.cpp create mode 100644 tools/lldb-mi/MIUtilString.h create mode 100644 tools/lldb-mi/MIUtilSystemLinux.cpp create mode 100644 tools/lldb-mi/MIUtilSystemLinux.h create mode 100644 tools/lldb-mi/MIUtilSystemOsx.cpp create mode 100644 tools/lldb-mi/MIUtilSystemOsx.h create mode 100644 tools/lldb-mi/MIUtilSystemWindows.cpp create mode 100644 tools/lldb-mi/MIUtilSystemWindows.h create mode 100644 tools/lldb-mi/MIUtilTermios.cpp create mode 100644 tools/lldb-mi/MIUtilTermios.h create mode 100644 tools/lldb-mi/MIUtilThreadBaseStd.cpp create mode 100644 tools/lldb-mi/MIUtilThreadBaseStd.h create mode 100644 tools/lldb-mi/MIUtilVariant.cpp create mode 100644 tools/lldb-mi/MIUtilVariant.h create mode 100644 tools/lldb-mi/Platform.cpp create mode 100644 tools/lldb-mi/Platform.h diff --git a/include/lldb/API/SBBreakpoint.h b/include/lldb/API/SBBreakpoint.h index be9c499798e1..86d49c29a821 100644 --- a/include/lldb/API/SBBreakpoint.h +++ b/include/lldb/API/SBBreakpoint.h @@ -117,7 +117,13 @@ public: void SetCallback (BreakpointHitCallback callback, void *baton); - + + void + SetScriptCallbackFunction (const char *callback_function_name); + + SBError + SetScriptCallbackBody (const char *script_body_text); + size_t GetNumResolvedLocations() const; diff --git a/include/lldb/API/SBBreakpointLocation.h b/include/lldb/API/SBBreakpointLocation.h index 3b2ca2cf88e8..fd9f246de4ff 100644 --- a/include/lldb/API/SBBreakpointLocation.h +++ b/include/lldb/API/SBBreakpointLocation.h @@ -58,6 +58,12 @@ public: const char * GetCondition (); + void + SetScriptCallbackFunction (const char *callback_function_name); + + SBError + SetScriptCallbackBody (const char *script_body_text); + void SetThreadID (lldb::tid_t sb_thread_id); diff --git a/include/lldb/API/SBDefines.h b/include/lldb/API/SBDefines.h index 8779d43d1f40..30ea0dfda56e 100644 --- a/include/lldb/API/SBDefines.h +++ b/include/lldb/API/SBDefines.h @@ -21,62 +21,71 @@ #include "lldb/lldb-types.h" #include "lldb/lldb-versioning.h" -// Forward Declarations +#ifdef SWIG +#define LLDB_API +#endif +// Forward Declarations namespace lldb { -class SBAddress; -class SBBlock; -class SBBreakpoint; -class SBBreakpointLocation; -class SBBroadcaster; -class SBCommand; -class SBCommandInterpreter; -class SBCommandPluginInterface; -class SBCommandReturnObject; -class SBCommunication; -class SBCompileUnit; -class SBData; -class SBDebugger; -class SBDeclaration; -class SBError; -class SBEvent; -class SBEventList; -class SBExpressionOptions; -class SBFileSpec; -class SBFileSpecList; -class SBFrame; -class SBFunction; -class SBHostOS; -class SBInstruction; -class SBInstructionList; -class SBLineEntry; -class SBListener; -class SBModule; -class SBModuleSpec; -class SBModuleSpecList; -class SBProcess; -class SBSourceManager; -class SBStream; -class SBStringList; -class SBSymbol; -class SBSymbolContext; -class SBSymbolContextList; -class SBTarget; -class SBThread; -class SBType; -class SBTypeCategory; -class SBTypeFilter; -class SBTypeFormat; -class SBTypeNameSpecifier; -class SBTypeSummary; +class LLDB_API SBAddress; +class LLDB_API SBBlock; +class LLDB_API SBBreakpoint; +class LLDB_API SBBreakpointLocation; +class LLDB_API SBBroadcaster; +class LLDB_API SBCommand; +class LLDB_API SBCommandInterpreter; +class LLDB_API SBCommandPluginInterface; +class LLDB_API SBCommandReturnObject; +class LLDB_API SBCommunication; +class LLDB_API SBCompileUnit; +class LLDB_API SBData; +class LLDB_API SBDebugger; +class LLDB_API SBDeclaration; +class LLDB_API SBError; +class LLDB_API SBEvent; +class LLDB_API SBEventList; +class LLDB_API SBExpressionOptions; +class LLDB_API SBFileSpec; +class LLDB_API SBFileSpecList; +class LLDB_API SBFrame; +class LLDB_API SBFunction; +class LLDB_API SBHostOS; +class LLDB_API SBInstruction; +class LLDB_API SBInstructionList; +class LLDB_API SBLineEntry; +class LLDB_API SBListener; +class LLDB_API SBModule; +class LLDB_API SBModuleSpec; +class LLDB_API SBModuleSpecList; +class LLDB_API SBProcess; +class LLDB_API SBQueue; +class LLDB_API SBQueueItem; +class LLDB_API SBSection; +class LLDB_API SBSourceManager; +class LLDB_API SBStream; +class LLDB_API SBStringList; +class LLDB_API SBSymbol; +class LLDB_API SBSymbolContext; +class LLDB_API SBSymbolContextList; +class LLDB_API SBTarget; +class LLDB_API SBThread; +class LLDB_API SBType; +class LLDB_API SBTypeCategory; +class LLDB_API SBTypeEnumMember; +class LLDB_API SBTypeEnumMemberList; +class LLDB_API SBTypeFilter; +class LLDB_API SBTypeFormat; +class LLDB_API SBTypeNameSpecifier; +class LLDB_API SBTypeSummary; #ifndef LLDB_DISABLE_PYTHON -class SBTypeSynthetic; +class LLDB_API SBTypeSynthetic; #endif -class SBTypeList; -class SBValue; -class SBValueList; -class SBWatchpoint; +class LLDB_API SBTypeList; +class LLDB_API SBValue; +class LLDB_API SBValueList; +class LLDB_API SBWatchpoint; +class LLDB_API SBUnixSignals; } diff --git a/include/lldb/API/SBError.h b/include/lldb/API/SBError.h index 25d7e81a3be5..b9908658c5bc 100644 --- a/include/lldb/API/SBError.h +++ b/include/lldb/API/SBError.h @@ -77,6 +77,8 @@ protected: friend class SBTarget; friend class SBValue; friend class SBWatchpoint; + friend class SBBreakpoint; + friend class SBBreakpointLocation; lldb_private::Error * get(); diff --git a/include/lldb/API/SBExpressionOptions.h b/include/lldb/API/SBExpressionOptions.h index 6a3a640432f6..c3592880c46a 100644 --- a/include/lldb/API/SBExpressionOptions.h +++ b/include/lldb/API/SBExpressionOptions.h @@ -56,20 +56,54 @@ public: uint32_t GetTimeoutInMicroSeconds () const; + // Set the timeout for the expression, 0 means wait forever. void SetTimeoutInMicroSeconds (uint32_t timeout = 0); + uint32_t + GetOneThreadTimeoutInMicroSeconds () const; + + // Set the timeout for running on one thread, 0 means use the default behavior. + // If you set this higher than the overall timeout, you'll get an error when you + // try to run the expression. + void + SetOneThreadTimeoutInMicroSeconds (uint32_t timeout = 0); + bool GetTryAllThreads () const; void SetTryAllThreads (bool run_others = true); + + bool + GetStopOthers() const; + + void + SetStopOthers(bool stop_others = true); bool GetTrapExceptions () const; void SetTrapExceptions (bool trap_exceptions = true); + + void + SetLanguage (lldb::LanguageType language); + + void + SetCancelCallback (lldb::ExpressionCancelCallback callback, void *baton); + + bool + GetGenerateDebugInfo (); + + void + SetGenerateDebugInfo (bool b = true); + + bool + GetSuppressPersistentResult (); + + void + SetSuppressPersistentResult (bool b = false); protected: diff --git a/include/lldb/API/SBFileSpec.h b/include/lldb/API/SBFileSpec.h index 5d4447f74e64..d262b98d0fd7 100644 --- a/include/lldb/API/SBFileSpec.h +++ b/include/lldb/API/SBFileSpec.h @@ -21,7 +21,7 @@ public: SBFileSpec (const lldb::SBFileSpec &rhs); - SBFileSpec (const char *path);// Deprected, use SBFileSpec (const char *path, bool resolve) + SBFileSpec (const char *path);// Deprecated, use SBFileSpec (const char *path, bool resolve) SBFileSpec (const char *path, bool resolve); diff --git a/include/lldb/API/SBFrame.h b/include/lldb/API/SBFrame.h index 4ae38c13bede..f6b84ab1ddac 100644 --- a/include/lldb/API/SBFrame.h +++ b/include/lldb/API/SBFrame.h @@ -75,7 +75,7 @@ public: /// Get the appropriate function name for this frame. Inlined functions in /// LLDB are represented by Blocks that have inlined function information, so /// just looking at the SBFunction or SBSymbol for a frame isn't enough. - /// This function will return the appriopriate function, symbol or inlined + /// This function will return the appropriate function, symbol or inlined /// function name for the frame. /// /// This function returns: diff --git a/include/lldb/API/SBHostOS.h b/include/lldb/API/SBHostOS.h index e5fab6fe7849..7ab22caaaad9 100644 --- a/include/lldb/API/SBHostOS.h +++ b/include/lldb/API/SBHostOS.h @@ -25,12 +25,15 @@ public: static lldb::SBFileSpec GetLLDBPythonPath (); + static lldb::SBFileSpec + GetLLDBPath (lldb::PathType path_type); + static void ThreadCreated (const char *name); static lldb::thread_t ThreadCreate (const char *name, - thread_func_t thread_function, + lldb::thread_func_t thread_function, void *thread_arg, lldb::SBError *err); @@ -43,7 +46,7 @@ public: lldb::SBError *err); static bool ThreadJoin (lldb::thread_t thread, - thread_result_t *result, + lldb::thread_result_t *result, lldb::SBError *err); diff --git a/include/lldb/API/SBListener.h b/include/lldb/API/SBListener.h index c5a047341741..4a11ec1072f1 100644 --- a/include/lldb/API/SBListener.h +++ b/include/lldb/API/SBListener.h @@ -55,7 +55,7 @@ public: StopListeningForEvents (const lldb::SBBroadcaster& broadcaster, uint32_t event_mask); - // Returns true if an event was recieved, false if we timed out. + // Returns true if an event was received, false if we timed out. bool WaitForEvent (uint32_t num_seconds, lldb::SBEvent &event); diff --git a/include/lldb/API/SBProcess.h b/include/lldb/API/SBProcess.h index f2846710c614..4b59462ca3f1 100644 --- a/include/lldb/API/SBProcess.h +++ b/include/lldb/API/SBProcess.h @@ -221,6 +221,9 @@ public: lldb::SBError Signal (int signal); + lldb::SBUnixSignals + GetUnixSignals(); + void SendAsyncInterrupt(); @@ -279,6 +282,9 @@ public: lldb::SBError UnloadImage (uint32_t image_token); + lldb::SBError + SendEventData (const char *data); + //------------------------------------------------------------------ /// Return the number of different thread-origin extended backtraces /// this process can support. diff --git a/include/lldb/API/SBQueue.h b/include/lldb/API/SBQueue.h index 6ab9aa09f466..fbb1952902f8 100644 --- a/include/lldb/API/SBQueue.h +++ b/include/lldb/API/SBQueue.h @@ -14,7 +14,6 @@ #include "lldb/lldb-forward.h" #include "lldb/API/SBDefines.h" -#include "lldb/API/SBQueueItem.h" namespace lldb { @@ -62,8 +61,15 @@ public: lldb::SBQueueItem GetPendingItemAtIndex (uint32_t); + uint32_t + GetNumRunningItems (); + + lldb::QueueKind + GetKind (); + protected: friend class SBProcess; + friend class SBThread; void SetQueue (const lldb::QueueSP& queue_sp); diff --git a/include/lldb/API/SBQueueItem.h b/include/lldb/API/SBQueueItem.h index 355c5ac90a23..c90f36eeb573 100644 --- a/include/lldb/API/SBQueueItem.h +++ b/include/lldb/API/SBQueueItem.h @@ -12,7 +12,6 @@ #include "lldb/API/SBDefines.h" #include "lldb/API/SBAddress.h" -#include "lldb/API/SBThread.h" namespace lldb { diff --git a/include/lldb/API/SBStream.h b/include/lldb/API/SBStream.h index 038adf68542c..fb69c12f0a91 100644 --- a/include/lldb/API/SBStream.h +++ b/include/lldb/API/SBStream.h @@ -51,7 +51,7 @@ public: RedirectToFileDescriptor (int fd, bool transfer_fh_ownership); // If the stream is redirected to a file, forget about the file and if - // ownership of the file was transfered to this object, close the file. + // ownership of the file was transferred to this object, close the file. // If the stream is backed by a local cache, clear this cache. void Clear (); @@ -86,6 +86,7 @@ protected: friend class SBTarget; friend class SBThread; friend class SBType; + friend class SBTypeEnumMember; friend class SBTypeMember; friend class SBValue; friend class SBWatchpoint; diff --git a/include/lldb/API/SBTarget.h b/include/lldb/API/SBTarget.h index 230dffc68251..370d40d0454a 100644 --- a/include/lldb/API/SBTarget.h +++ b/include/lldb/API/SBTarget.h @@ -47,6 +47,35 @@ public: 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); + uint32_t GetNumArguments (); @@ -110,6 +139,18 @@ public: 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; @@ -331,7 +372,7 @@ public: /// Some launch options specified by logical OR'ing /// lldb::LaunchFlags enumeration values together. /// - /// @param[in] stop_at_endtry + /// @param[in] stop_at_entry /// If false do not stop the inferior at the entry point. /// /// @param[out] @@ -580,7 +621,7 @@ public: //------------------------------------------------------------------ - /// The the section base load addresses for all sections in a module. + /// Clear the section base load addresses for all sections in a module. /// /// @param[in] module /// The module to unload. diff --git a/include/lldb/API/SBThread.h b/include/lldb/API/SBThread.h index 04b6c86e6d89..07a43ebee7ce 100644 --- a/include/lldb/API/SBThread.h +++ b/include/lldb/API/SBThread.h @@ -41,6 +41,9 @@ public: ~SBThread(); + lldb::SBQueue + GetQueue () const; + bool IsValid() const; @@ -97,6 +100,9 @@ public: lldb::queue_id_t GetQueueID() const; + bool + GetInfoItemByPathAsString ( const char *path, SBStream &strm); + void StepOver (lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping); @@ -136,8 +142,8 @@ public: /// the other threads in a process are allowed to run. So when /// SBProcess::Continue() is called, any threads that aren't suspended will /// be allowed to run. If any of the SBThread functions for stepping are - /// called (StepOver, StepInto, StepOut, StepInstruction, RunToAddres), the - /// thread will not be allowed to run and these funtions will simply return. + /// called (StepOver, StepInto, StepOut, StepInstruction, RunToAddress), the + /// thread will not be allowed to run and these functions will simply return. /// /// Eventually we plan to add support for thread centric debugging where /// each thread is controlled individually and each thread would broadcast @@ -207,6 +213,9 @@ public: uint32_t GetExtendedBacktraceOriginatingIndexID (); + bool + SafeToCallFunctions (); + protected: friend class SBBreakpoint; friend class SBBreakpointLocation; diff --git a/include/lldb/API/SBType.h b/include/lldb/API/SBType.h index 2cd9b4459a33..363aa59e35aa 100644 --- a/include/lldb/API/SBType.h +++ b/include/lldb/API/SBType.h @@ -143,6 +143,9 @@ public: lldb::SBTypeMember GetVirtualBaseClassAtIndex (uint32_t idx); + lldb::SBTypeEnumMemberList + GetEnumMembers(); + uint32_t GetNumberOfTemplateArguments (); @@ -161,6 +164,9 @@ public: const char* GetName(); + const char * + GetDisplayTypeName (); + lldb::TypeClass GetTypeClass (); @@ -199,6 +205,8 @@ protected: friend class SBFunction; friend class SBModule; friend class SBTarget; + friend class SBTypeEnumMember; + friend class SBTypeEnumMemberList; friend class SBTypeNameSpecifier; friend class SBTypeMember; friend class SBTypeList; diff --git a/include/lldb/API/SBTypeEnumMember.h b/include/lldb/API/SBTypeEnumMember.h new file mode 100644 index 000000000000..75c9917989c2 --- /dev/null +++ b/include/lldb/API/SBTypeEnumMember.h @@ -0,0 +1,98 @@ + +//===-- SBTypeEnumMember.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_SBTypeEnumMember_h_ +#define LLDB_SBTypeEnumMember_h_ + +#include "lldb/API/SBDefines.h" + +namespace lldb { + +class SBTypeEnumMember +{ +public: + SBTypeEnumMember (); + + SBTypeEnumMember (const SBTypeEnumMember& rhs); + + ~SBTypeEnumMember(); + + SBTypeEnumMember& + operator = (const SBTypeEnumMember& rhs); + + bool + IsValid() const; + + int64_t + GetValueAsSigned(); + + uint64_t + GetValueAsUnsigned(); + + const char * + GetName (); + + lldb::SBType + GetType (); + + bool + GetDescription (lldb::SBStream &description, + lldb::DescriptionLevel description_level); + +protected: + friend class SBType; + friend class SBTypeEnumMemberList; + + void + reset (lldb_private::TypeEnumMemberImpl *); + + lldb_private::TypeEnumMemberImpl & + ref (); + + const lldb_private::TypeEnumMemberImpl & + ref () const; + + lldb::TypeEnumMemberImplSP m_opaque_sp; + + SBTypeEnumMember (const lldb::TypeEnumMemberImplSP &); +}; + +class SBTypeEnumMemberList +{ +public: + SBTypeEnumMemberList(); + + SBTypeEnumMemberList(const SBTypeEnumMemberList& rhs); + + ~SBTypeEnumMemberList(); + + SBTypeEnumMemberList& + operator = (const SBTypeEnumMemberList& rhs); + + bool + IsValid(); + + void + Append (SBTypeEnumMember entry); + + SBTypeEnumMember + GetTypeEnumMemberAtIndex (uint32_t index); + + uint32_t + GetSize(); + + +private: + std::unique_ptr m_opaque_ap; +}; + +} // namespace lldb + +#endif // LLDB_SBTypeEnumMember_h_ diff --git a/include/lldb/API/SBUnixSignals.h b/include/lldb/API/SBUnixSignals.h new file mode 100644 index 000000000000..40bbed8b48ef --- /dev/null +++ b/include/lldb/API/SBUnixSignals.h @@ -0,0 +1,84 @@ +//===-- SBUnixSignals.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_SBUnixSignals_h_ +#define LLDB_SBUnixSignals_h_ + +#include "lldb/API/SBDefines.h" + +namespace lldb { + +class SBUnixSignals { +public: + SBUnixSignals (); + + SBUnixSignals (const lldb::SBUnixSignals &rhs); + + ~SBUnixSignals(); + + const SBUnixSignals & + operator =(const lldb::SBUnixSignals &rhs); + + void + Clear (); + + bool + IsValid () const; + + const char * + GetSignalAsCString (int32_t signo) const; + + int32_t + GetSignalNumberFromName (const char *name) const; + + bool + GetShouldSuppress (int32_t signo) const; + + bool + SetShouldSuppress (int32_t signo, + bool value); + + bool + GetShouldStop (int32_t signo) const; + + bool + SetShouldStop (int32_t signo, + bool value); + + bool + GetShouldNotify (int32_t signo) const; + + bool + SetShouldNotify (int32_t signo, bool value); + + int32_t + GetNumSignals () const; + + int32_t + GetSignalAtIndex (int32_t index) const; + +protected: + friend class SBProcess; + + SBUnixSignals (lldb::ProcessSP &process_sp); + + lldb::ProcessSP + GetSP() const; + + void + SetSP (const lldb::ProcessSP &process_sp); + +private: + lldb::ProcessWP m_opaque_wp; +}; + + +} // namespace lldb + +#endif // LLDB_SBUnixSignals_h_ diff --git a/include/lldb/API/SBValue.h b/include/lldb/API/SBValue.h index 2b9a344b9300..93b869ba9c5c 100644 --- a/include/lldb/API/SBValue.h +++ b/include/lldb/API/SBValue.h @@ -50,6 +50,9 @@ public: const char * GetTypeName (); + + const char * + GetDisplayTypeName (); size_t GetByteSize (); @@ -173,7 +176,7 @@ public: //------------------------------------------------------------------ /// Get a child value by index from a value. /// - /// Structs, unions, classes, arrays and and pointers have child + /// Structs, unions, classes, arrays and pointers have child /// values that can be access by index. /// /// Structs and unions access child members using a zero based index @@ -208,7 +211,7 @@ public: /// The index of the child value to get /// /// @param[in] use_dynamic - /// An enumeration that specifies wether to get dynamic values, + /// An enumeration that specifies whether to get dynamic values, /// and also if the target can be run to figure out the dynamic /// type of the child value. /// diff --git a/include/lldb/Breakpoint/Breakpoint.h b/include/lldb/Breakpoint/Breakpoint.h index 749ff8d1a09c..15693f86e382 100644 --- a/include/lldb/Breakpoint/Breakpoint.h +++ b/include/lldb/Breakpoint/Breakpoint.h @@ -431,7 +431,7 @@ public: /// @param[in] is_synchronous /// If \b true the callback will be run on the private event thread /// before the stop event gets reported. If false, the callback will get - /// handled on the public event thead after the stop has been posted. + /// handled on the public event thread after the stop has been posted. /// /// @return /// \b true if the process should stop when you hit the breakpoint. diff --git a/include/lldb/Breakpoint/BreakpointLocationList.h b/include/lldb/Breakpoint/BreakpointLocationList.h index ec34641b727c..0d8062eb644c 100644 --- a/include/lldb/Breakpoint/BreakpointLocationList.h +++ b/include/lldb/Breakpoint/BreakpointLocationList.h @@ -143,7 +143,7 @@ public: ClearAllBreakpointSites (); //------------------------------------------------------------------ - /// Tells all the breakopint locations in this list to attempt to + /// Tells all the breakpoint locations in this list to attempt to /// resolve any possible breakpoint sites. //------------------------------------------------------------------ void diff --git a/include/lldb/Breakpoint/BreakpointOptions.h b/include/lldb/Breakpoint/BreakpointOptions.h index 728f5932fa06..eb374ad69603 100644 --- a/include/lldb/Breakpoint/BreakpointOptions.h +++ b/include/lldb/Breakpoint/BreakpointOptions.h @@ -145,7 +145,8 @@ public: /// @return /// The synchronicity of our callback. //------------------------------------------------------------------ - bool IsCallbackSynchronous () { + bool IsCallbackSynchronous () const + { return m_callback_is_synchronous; } @@ -280,7 +281,7 @@ public: /// Returns true if the breakpoint option has a callback set. //------------------------------------------------------------------ bool - HasCallback(); + HasCallback() const; //------------------------------------------------------------------ /// This is the default empty callback. diff --git a/include/lldb/Breakpoint/BreakpointSite.h b/include/lldb/Breakpoint/BreakpointSite.h index 271a23c2e451..1d2cbea18f9f 100644 --- a/include/lldb/Breakpoint/BreakpointSite.h +++ b/include/lldb/Breakpoint/BreakpointSite.h @@ -19,6 +19,7 @@ // Project includes #include "lldb/lldb-private.h" +#include "lldb/Host/Mutex.h" #include "lldb/Core/UserID.h" #include "lldb/Breakpoint/StoppointLocation.h" #include "lldb/Breakpoint/BreakpointLocationCollection.h" @@ -33,7 +34,7 @@ namespace lldb_private { /// The BreakpointSite class handles the physical breakpoint that is /// actually inserted in the target program. As such, it is also the /// one that gets hit, when the program stops. It keeps a list of all -/// BreakpointLocations that share this phsyical site. When the +/// BreakpointLocations that share this physical site. When the /// breakpoint is hit, all the locations are informed by the breakpoint /// site. Breakpoint sites are owned by the process. //---------------------------------------------------------------------- @@ -50,7 +51,7 @@ public: // and m_trap_opcode contain the saved and written opcode. eHardware, // Breakpoint site is set as a hardware breakpoint eExternal // Breakpoint site is managed by an external debug nub or - // debug interface where memory reads trasparently will not + // debug interface where memory reads transparently will not // display any breakpoint opcodes. }; @@ -123,7 +124,7 @@ public: /// Sets whether the current breakpoint site is enabled or not /// /// @param[in] enabled - /// \b true if the breakoint is enabled, \b false otherwise. + /// \b true if the breakpoint is enabled, \b false otherwise. //------------------------------------------------------------------ void SetEnabled (bool enabled); @@ -172,7 +173,7 @@ public: GetNumberOfOwners (); //------------------------------------------------------------------ - /// This method returns the the breakpoint location at index \a index + /// This method returns the breakpoint location at index \a index /// located at this breakpoint site. The owners are listed ordinally /// from 0 to GetNumberOfOwners() - 1 so you can use this method to iterate /// over the owners @@ -257,6 +258,7 @@ public: private: friend class Process; + friend class BreakpointLocation; //------------------------------------------------------------------ /// The method removes the owner at \a break_loc_id from this breakpoint list. @@ -276,6 +278,7 @@ private: // Consider adding an optimization where if there is only one // owner, we don't store a list. The usual case will be only one owner... BreakpointLocationCollection m_owners; ///< This has the BreakpointLocations that share this breakpoint site. + Mutex m_owners_mutex; ///< This mutex protects the owners collection. static lldb::break_id_t GetNextID(); diff --git a/include/lldb/Breakpoint/Watchpoint.h b/include/lldb/Breakpoint/Watchpoint.h index 5dbed03d5406..8493775eec34 100644 --- a/include/lldb/Breakpoint/Watchpoint.h +++ b/include/lldb/Breakpoint/Watchpoint.h @@ -134,7 +134,7 @@ public: /// @param[in] is_synchronous /// If \b true the callback will be run on the private event thread /// before the stop event gets reported. If false, the callback will get - /// handled on the public event thead after the stop has been posted. + /// handled on the public event thread after the stop has been posted. /// /// @return /// \b true if the process should stop when you hit the watchpoint. @@ -215,7 +215,7 @@ private: // undergoing a pair of temporary disable/enable actions to avoid recursively // triggering further watchpoint events. uint32_t m_disabled_count; // Keep track of the count that the watchpoint is disabled while in ephemeral mode. - // At the end of the ephemeral mode when the watchpoint is to be enabled agian, + // At the end of the ephemeral mode when the watchpoint is to be enabled again, // we check the count, if it is more than 1, it means the user-supplied actions // actually want the watchpoint to be disabled! uint32_t m_watch_read:1, // 1 if we stop when the watched data is read from diff --git a/include/lldb/Core/Address.h b/include/lldb/Core/Address.h index 322019395ae7..8dd2339f9207 100644 --- a/include/lldb/Core/Address.h +++ b/include/lldb/Core/Address.h @@ -230,7 +230,7 @@ public: /// offset based address, and \a style lets the user choose. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. /// /// @param[in] style /// The display style for the address. @@ -310,7 +310,7 @@ public: /// /// This function will first resolve its address to a load address. /// Then, if the address turns out to be in code address, return the - /// load address for a an opcode. This address object might have + /// load address for an opcode. This address object might have /// extra bits set (bit zero will be set to Thumb functions for an /// ARM target) that are required for changing the program counter /// and this function will remove any bits that are intended for @@ -362,7 +362,7 @@ public: /// offset (for absolute addresses that have no section). /// /// @return - /// Returns \b true if the the offset is valid, \b false + /// Returns \b true if the offset is valid, \b false /// otherwise. //------------------------------------------------------------------ bool diff --git a/include/lldb/Core/AddressRange.h b/include/lldb/Core/AddressRange.h index bd3ab2ab5da5..9d781f3e85ae 100644 --- a/include/lldb/Core/AddressRange.h +++ b/include/lldb/Core/AddressRange.h @@ -189,7 +189,7 @@ public: /// how the base address gets displayed. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. /// /// @param[in] style /// The display style for the address. @@ -215,7 +215,7 @@ public: /// and pointer values, reference counts, etc. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. //------------------------------------------------------------------ void DumpDebug (Stream *s) const; diff --git a/include/lldb/Core/ArchSpec.h b/include/lldb/Core/ArchSpec.h index 1ccb385783a0..255beee573b6 100644 --- a/include/lldb/Core/ArchSpec.h +++ b/include/lldb/Core/ArchSpec.h @@ -50,6 +50,7 @@ public: eCore_arm_armv7m, eCore_arm_armv7em, eCore_arm_xscale, + eCore_thumb, eCore_thumbv4t, eCore_thumbv5, @@ -57,11 +58,14 @@ public: eCore_thumbv6, eCore_thumbv6m, eCore_thumbv7, - eCore_thumbv7f, eCore_thumbv7s, eCore_thumbv7k, + eCore_thumbv7f, eCore_thumbv7m, eCore_thumbv7em, + eCore_arm_arm64, + eCore_arm_armv8, + eCore_arm_aarch64, eCore_mips64, @@ -89,6 +93,7 @@ public: eCore_x86_32_i386, eCore_x86_32_i486, eCore_x86_32_i486sx, + eCore_x86_32_i686, eCore_x86_64_x86_64, eCore_x86_64_x86_64h, // Haswell enabled x86_64 @@ -98,6 +103,12 @@ public: eCore_uknownMach32, eCore_uknownMach64, + + eCore_kalimba, + eCore_kalimba3, + eCore_kalimba4, + eCore_kalimba5, + kNumCores, kCore_invalid, @@ -107,6 +118,7 @@ public: kCore_ppc_any, kCore_ppc64_any, kCore_x86_32_any, + kCore_x86_64_any, kCore_hexagon_any, kCore_arm_first = eCore_arm_generic, @@ -122,10 +134,16 @@ public: kCore_ppc64_last = eCore_ppc64_ppc970_64, kCore_x86_32_first = eCore_x86_32_i386, - kCore_x86_32_last = eCore_x86_32_i486sx, + kCore_x86_32_last = eCore_x86_32_i686, + + kCore_x86_64_first = eCore_x86_64_x86_64, + kCore_x86_64_last = eCore_x86_64_x86_64h, kCore_hexagon_first = eCore_hexagon_generic, - kCore_hexagon_last = eCore_hexagon_hexagonv5 + kCore_hexagon_last = eCore_hexagon_hexagonv5, + + kCore_kalimba_first = eCore_kalimba, + kCore_kalimba_last = eCore_kalimba5 }; //------------------------------------------------------------------ @@ -228,7 +246,7 @@ public: /// /// This will be something like "ubuntu", "fedora", etc. on Linux. /// This should be the same value returned by - /// Host::GetDistributionId (). + /// HostInfo::GetDistributionId (). ///------------------------------------------------------------------ void SetDistributionId (const char* distribution_id); @@ -302,7 +320,7 @@ public: /// /// @param[in] cpu The required CPU type. /// - /// @return True if the object and CPU type were sucessfully set. + /// @return True if the object and CPU type were successfully set. //------------------------------------------------------------------ bool SetArchitecture (ArchitectureType arch_type, @@ -350,6 +368,24 @@ public: uint32_t GetMachOCPUSubType () const; + //------------------------------------------------------------------ + /// Architecture data byte width accessor + /// + /// @return the size in 8-bit (host) bytes of a minimum addressable + /// unit from the Architecture's data bus + //------------------------------------------------------------------ + uint32_t + GetDataByteSize() const; + + //------------------------------------------------------------------ + /// Architecture code byte width accessor + /// + /// @return the size in 8-bit (host) bytes of a minimum addressable + /// unit from the Architecture's code bus + //------------------------------------------------------------------ + uint32_t + GetCodeByteSize() const; + //------------------------------------------------------------------ /// Architecture tripple accessor. /// diff --git a/include/lldb/Core/ClangForward.h b/include/lldb/Core/ClangForward.h index 0b3f13a16602..ef7308d25f7f 100644 --- a/include/lldb/Core/ClangForward.h +++ b/include/lldb/Core/ClangForward.h @@ -58,6 +58,7 @@ namespace clang class DiagnosticsEngine; class DiagnosticOptions; class EnumDecl; + class EnumConstantDecl; class Expr; class ExternalASTSource; class ExtVectorElementExpr; diff --git a/include/lldb/Core/Communication.h b/include/lldb/Core/Communication.h index 2dde55044171..7e8209d7d9c6 100644 --- a/include/lldb/Core/Communication.h +++ b/include/lldb/Core/Communication.h @@ -59,7 +59,7 @@ namespace lldb_private { /// /// bool Communication::StartReadThread (Error *); /// -/// If true is returned a read thead has been spawned that will +/// If true is returned a read thread has been spawned that will /// continually execute a call to the pure virtual DoRead function: /// /// size_t Communication::ReadFromConnection (void *, size_t, uint32_t); @@ -300,7 +300,7 @@ public: //------------------------------------------------------------------ /// The static read thread function. This function will call /// the "DoRead" function continuously and wait for data to become - /// avaialble. When data is received it will append the available + /// available. When data is received it will append the available /// data to the internal cache and broadcast a /// \b eBroadcastBitReadThreadGotBytes event. /// diff --git a/include/lldb/Core/ConnectionFileDescriptor.h b/include/lldb/Core/ConnectionFileDescriptor.h index 15598c9b1335..75d0202fcf6c 100644 --- a/include/lldb/Core/ConnectionFileDescriptor.h +++ b/include/lldb/Core/ConnectionFileDescriptor.h @@ -10,24 +10,23 @@ #ifndef liblldb_ConnectionFileDescriptor_h_ #define liblldb_ConnectionFileDescriptor_h_ -// C Includes -#ifndef _WIN32 -#include -#include -#include -#endif - // C++ Includes #include +#include "lldb/lldb-forward.h" + // Other libraries and framework includes // Project includes #include "lldb/Core/Connection.h" #include "lldb/Host/Mutex.h" +#include "lldb/Host/Pipe.h" #include "lldb/Host/Predicate.h" +#include "lldb/Host/IOObject.h" namespace lldb_private { +class Error; +class Socket; class SocketAddress; class ConnectionFileDescriptor : @@ -64,81 +63,52 @@ public: lldb::ConnectionStatus &status, Error *error_ptr); - // If the read file descriptor is a socket, then return - // the port number that is being used by the socket. - uint16_t - GetReadPort () const; - - // If the write file descriptor is a socket, then return - // the port number that is being used by the socket. - uint16_t - GetWritePort () const; + lldb::ConnectionStatus + BytesAvailable (uint32_t timeout_usec, Error *error_ptr); - uint16_t - GetBoundPort (uint32_t timeout_sec); + bool + InterruptRead (); -protected: + lldb::IOObjectSP GetReadObject() { return m_read_sp; } + const lldb::IOObjectSP GetReadObject() const { return m_read_sp; } - typedef enum - { - eFDTypeFile, // Other FD requireing read/write - eFDTypeSocket, // Socket requiring send/recv - eFDTypeSocketUDP // Unconnected UDP socket requiring sendto/recvfrom - } FDType; + uint16_t GetListeningPort(uint32_t timeout_sec); + +protected: void OpenCommandPipe (); void CloseCommandPipe (); - - lldb::ConnectionStatus - BytesAvailable (uint32_t timeout_usec, Error *error_ptr); lldb::ConnectionStatus SocketListen (const char *host_and_port, Error *error_ptr); - + lldb::ConnectionStatus ConnectTCP (const char *host_and_port, Error *error_ptr); - + lldb::ConnectionStatus ConnectUDP (const char *args, Error *error_ptr); - lldb::ConnectionStatus - NamedSocketAccept (const char *socket_name, Error *error_ptr); - lldb::ConnectionStatus NamedSocketConnect (const char *socket_name, Error *error_ptr); - + lldb::ConnectionStatus - Close (int& fd, FDType type, Error *error); - - int m_fd_send; - int m_fd_recv; - FDType m_fd_send_type; - FDType m_fd_recv_type; - std::unique_ptr m_udp_send_sockaddr; - uint32_t m_socket_timeout_usec; - int m_pipe_read; // A pipe that we select on the reading end of along with - int m_pipe_write; // m_fd_recv so we can force ourselves out of the select. - Mutex m_mutex; - Predicate m_port_predicate; // Used when binding to port zero to wait for the thread that creates the socket, binds and listens to resolve the port number - bool m_should_close_fd; // True if this class should close the file descriptor when it goes away. - bool m_shutting_down; // This marks that we are shutting down so if we get woken up from BytesAvailable - // to disconnect, we won't try to read again. + NamedSocketAccept (const char *socket_name, Error *error_ptr); - static uint16_t - GetSocketPort (int fd); - - static int - GetSocketOption(int fd, int level, int option_name, int &option_value); + lldb::IOObjectSP m_read_sp; + lldb::IOObjectSP m_write_sp; - static int - SetSocketOption(int fd, int level, int option_name, int option_value); - - bool - SetSocketReceiveTimeout (uint32_t timeout_usec); + Predicate m_port_predicate; // Used when binding to port zero to wait for the thread + // that creates the socket, binds and listens to resolve + // the port number. + Pipe m_pipe; + Mutex m_mutex; + bool m_shutting_down; // This marks that we are shutting down so if we get woken up from + // BytesAvailable to disconnect, we won't try to read again. + bool m_waiting_for_accept; private: DISALLOW_COPY_AND_ASSIGN (ConnectionFileDescriptor); }; diff --git a/include/lldb/Core/ConstString.h b/include/lldb/Core/ConstString.h index 684cc8f921ed..cfa237c46862 100644 --- a/include/lldb/Core/ConstString.h +++ b/include/lldb/Core/ConstString.h @@ -303,7 +303,7 @@ public: /// returns an integer result. /// /// NOTE: only call this function when you want a true string - /// comparision. If you want string equality use the, use the == + /// comparison. If you want string equality use the, use the == /// operator as it is much more efficient. Also if you want string /// inequality, use the != operator for the same reasons. /// @@ -383,7 +383,7 @@ public: //------------------------------------------------------------------ /// Set the C string value and its mangled counterpart. /// - /// Object files and debug sybmols often use mangled string to + /// Object files and debug symbols often use mangled string to /// represent the linkage name for a symbol, function or global. /// The string pool can efficiently store these values and their /// counterparts so when we run into another instance of a mangled @@ -406,7 +406,7 @@ public: /// Retrieve the mangled or demangled counterpart for a mangled /// or demangled ConstString. /// - /// Object files and debug sybmols often use mangled string to + /// Object files and debug symbols often use mangled string to /// represent the linkage name for a symbol, function or global. /// The string pool can efficiently store these values and their /// counterparts so when we run into another instance of a mangled @@ -478,7 +478,7 @@ public: //------------------------------------------------------------------ /// Get the size in bytes of the current global string pool. /// - /// Reports the the size in bytes of all shared C string values, + /// Reports the size in bytes of all shared C string values, /// containers and any other values as a byte size for the /// entire string pool. /// diff --git a/include/lldb/Core/DataBuffer.h b/include/lldb/Core/DataBuffer.h index e64245dead3d..64e2a8857837 100644 --- a/include/lldb/Core/DataBuffer.h +++ b/include/lldb/Core/DataBuffer.h @@ -20,7 +20,7 @@ namespace lldb_private { /// @class DataBuffer DataBuffer.h "lldb/Core/DataBuffer.h" /// @brief A pure virtual protocol class for abstracted data buffers. /// -/// DataBuffer is an abtract class that gets packaged into a shared pointer +/// DataBuffer is an abstract class that gets packaged into a shared pointer /// that can use to implement various ways to store data (on the heap, /// memory mapped, cached inferior memory). It gets used by DataExtractor /// so many DataExtractor objects can share the same data and sub-ranges diff --git a/include/lldb/Core/DataBufferHeap.h b/include/lldb/Core/DataBufferHeap.h index dac9a28befb9..ad73fabe5f1e 100644 --- a/include/lldb/Core/DataBufferHeap.h +++ b/include/lldb/Core/DataBufferHeap.h @@ -121,6 +121,9 @@ public: void CopyData (const void *src, lldb::offset_t src_len); + void + AppendData (const void *src, uint64_t src_len); + void Clear(); diff --git a/include/lldb/Core/DataBufferMemoryMap.h b/include/lldb/Core/DataBufferMemoryMap.h index d4a448a5df52..944b975a318a 100644 --- a/include/lldb/Core/DataBufferMemoryMap.h +++ b/include/lldb/Core/DataBufferMemoryMap.h @@ -100,7 +100,12 @@ public: /// @param[in] length /// The size in bytes that should be mapped starting \a offset /// bytes into the file. If \a length is \c SIZE_MAX, map - /// as many bytes as possible. + /// as many bytes as possible. Even though it may be possible + /// for a 32-bit host debugger to debug a 64-bit target, size_t + /// still dictates the maximum possible size that can be mapped + /// into this process. For this kind of cross-arch debugging + /// scenario, mappings and views should be managed at a higher + /// level. /// /// @return /// The number of bytes mapped starting from the \a offset. @@ -108,7 +113,7 @@ public: size_t MemoryMapFromFileSpec (const FileSpec* file, lldb::offset_t offset = 0, - lldb::offset_t length = SIZE_MAX, + size_t length = SIZE_MAX, bool writeable = false); //------------------------------------------------------------------ @@ -137,7 +142,7 @@ public: size_t MemoryMapFromFileDescriptor (int fd, lldb::offset_t offset, - lldb::offset_t length, + size_t length, bool write, bool fd_is_file); diff --git a/include/lldb/Core/DataEncoder.h b/include/lldb/Core/DataEncoder.h index 658cce0d2b4b..7cd5d6808152 100644 --- a/include/lldb/Core/DataEncoder.h +++ b/include/lldb/Core/DataEncoder.h @@ -173,7 +173,7 @@ public: } //------------------------------------------------------------------ - /// Get a the data start pointer. + /// Get the data start pointer. /// /// @return /// Returns a pointer to the first byte contained in this @@ -234,7 +234,7 @@ public: /// The size in byte of the integer to encode. /// /// @param[in] value - /// The integer value to write. The least significate bytes of + /// The integer value to write. The least significant bytes of /// the integer value will be written if the size is less than /// 8 bytes. /// @@ -253,7 +253,7 @@ public: /// start encoding. /// /// @param[int] src - /// The buffer that contains the the bytes to encode. + /// The buffer that contains the bytes to encode. /// /// @param[in] src_len /// The number of bytes to encode. diff --git a/include/lldb/Core/Debugger.h b/include/lldb/Core/Debugger.h index e80ec8516793..7ab62e5b7f3a 100644 --- a/include/lldb/Core/Debugger.h +++ b/include/lldb/Core/Debugger.h @@ -31,6 +31,14 @@ #include "lldb/Target/Platform.h" #include "lldb/Target/TargetList.h" +namespace llvm +{ +namespace sys +{ +class DynamicLibrary; +} +} + namespace lldb_private { //---------------------------------------------------------------------- @@ -51,9 +59,9 @@ friend class SourceManager; // For GetSourceFileCache. public: - typedef lldb::DynamicLibrarySP (*LoadPluginCallbackType) (const lldb::DebuggerSP &debugger_sp, - const FileSpec& spec, - Error& error); + typedef llvm::sys::DynamicLibrary (*LoadPluginCallbackType) (const lldb::DebuggerSP &debugger_sp, + const FileSpec& spec, + Error& error); static lldb::DebuggerSP CreateInstance (lldb::LogOutputCallback log_callback = NULL, void *baton = NULL); @@ -352,6 +360,13 @@ public: void CancelForwardEvents (const lldb::ListenerSP &listener_sp); + + bool + IsHandlingEvents () const + { + return IS_VALID_LLDB_HOST_THREAD(m_event_handler_thread); + } + protected: friend class CommandInterpreter; @@ -415,12 +430,11 @@ protected: lldb::StreamSP m_log_callback_stream_sp; ConstString m_instance_name; static LoadPluginCallbackType g_load_plugin_callback; - typedef std::vector LoadedPluginsList; + typedef std::vector LoadedPluginsList; LoadedPluginsList m_loaded_plugins; lldb::thread_t m_event_handler_thread; lldb::thread_t m_io_handler_thread; lldb::ListenerSP m_forward_listener_sp; - bool m_event_handler_thread_alive; void InstanceInitialize (); diff --git a/include/lldb/Core/EmulateInstruction.h b/include/lldb/Core/EmulateInstruction.h index 19a3269ae374..774d80968ff9 100644 --- a/include/lldb/Core/EmulateInstruction.h +++ b/include/lldb/Core/EmulateInstruction.h @@ -94,7 +94,7 @@ public: enum ContextType { eContextInvalid = 0, - // Read an instruciton opcode from memory + // Read an instruction opcode from memory eContextReadOpcode, // Usually used for writing a register value whose source value is an @@ -223,13 +223,13 @@ public: struct ISAAndImmediate { uint32_t isa; - uint32_t unsigned_data32; // immdiate data + uint32_t unsigned_data32; // immediate data } ISAAndImmediate; struct ISAAndImmediateSigned { uint32_t isa; - int32_t signed_data32; // signed immdiate data + int32_t signed_data32; // signed immediate data } ISAAndImmediateSigned; uint32_t isa; @@ -409,7 +409,7 @@ public: TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) = 0; virtual bool - GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo ®_info) = 0; + GetRegisterInfo (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterInfo ®_info) = 0; //---------------------------------------------------------------------- // Optional overrides @@ -421,7 +421,7 @@ public: CreateFunctionEntryUnwind (UnwindPlan &unwind_plan); static const char * - TranslateRegister (uint32_t reg_kind, uint32_t reg_num, std::string ®_name); + TranslateRegister (lldb::RegisterKind reg_kind, uint32_t reg_num, std::string ®_name); //---------------------------------------------------------------------- // RegisterInfo variants @@ -449,25 +449,25 @@ public: // Register kind and number variants //---------------------------------------------------------------------- bool - ReadRegister (uint32_t reg_kind, + ReadRegister (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterValue& reg_value); bool WriteRegister (const Context &context, - uint32_t reg_kind, + lldb::RegisterKind reg_kind, uint32_t reg_num, const RegisterValue& reg_value); uint64_t - ReadRegisterUnsigned (uint32_t reg_kind, + ReadRegisterUnsigned (lldb::RegisterKind reg_kind, uint32_t reg_num, uint64_t fail_value, bool *success_ptr); bool WriteRegisterUnsigned (const Context &context, - uint32_t reg_kind, + lldb::RegisterKind reg_kind, uint32_t reg_num, uint64_t reg_value); @@ -611,7 +611,7 @@ public: static bool GetBestRegisterKindAndNumber (const RegisterInfo *reg_info, - uint32_t ®_kind, + lldb::RegisterKind ®_kind, uint32_t ®_num); static uint32_t diff --git a/include/lldb/Core/Error.h b/include/lldb/Core/Error.h index 39c67f621c92..a1687689fc3f 100644 --- a/include/lldb/Core/Error.h +++ b/include/lldb/Core/Error.h @@ -209,6 +209,13 @@ public: void SetMachError (uint32_t err); + + void + SetExpressionError (lldb::ExpressionResults, const char *mssg); + + int + SetExpressionErrorWithFormat (lldb::ExpressionResults, const char *format, ...) __attribute__ ((format (printf, 3,4))); + //------------------------------------------------------------------ /// Set accesssor with an error value and type. /// @@ -301,7 +308,7 @@ protected: /// Member variables //------------------------------------------------------------------ ValueType m_code; ///< Error code as an integer value. - lldb::ErrorType m_type; ///< The type of the above error code. + lldb::ErrorType m_type; ///< The type of the above error code. mutable std::string m_string; ///< A string representation of the error code. }; diff --git a/include/lldb/Core/IOHandler.h b/include/lldb/Core/IOHandler.h index 78d1e7447db4..f477ebd48007 100644 --- a/include/lldb/Core/IOHandler.h +++ b/include/lldb/Core/IOHandler.h @@ -73,7 +73,7 @@ namespace lldb_private { // Called when CTRL+C is pressed which usually causes // Debugger::DispatchInputInterrupt to be called. - virtual void + virtual bool Interrupt () = 0; virtual void @@ -191,7 +191,7 @@ namespace lldb_private { /// /// This will return true if the input stream is a terminal (tty or /// pty) and can cause IO handlers to do different things (like - /// for a comfirmation when deleting all breakpoints). + /// for a confirmation when deleting all breakpoints). //------------------------------------------------------------------ bool GetIsInteractive (); @@ -200,9 +200,9 @@ namespace lldb_private { /// Check if the input is coming from a real terminal. /// /// A real terminal has a valid size with a certain number of rows - /// and colums. If this function returns true, then terminal escape + /// and columns. If this function returns true, then terminal escape /// sequences are expected to work (cursor movement escape sequences, - /// clearning lines, etc). + /// clearing lines, etc). //------------------------------------------------------------------ bool GetIsRealTerminal (); @@ -267,7 +267,7 @@ namespace lldb_private { //------------------------------------------------------------------ /// Called when a line or lines have been retrieved. /// - /// This funtion can handle the current line and possibly call + /// This function can handle the current line and possibly call /// IOHandler::SetIsDone(true) when the IO handler is done like when /// "quit" is entered as a command, of when an empty line is /// received. It is up to the delegate to determine when a line @@ -304,11 +304,22 @@ namespace lldb_private { virtual ConstString - GetControlSequence (char ch) + IOHandlerGetControlSequence (char ch) { return ConstString(); } + //------------------------------------------------------------------ + // Intercept the IOHandler::Interrupt() calls and do something. + // + // Return true if the interrupt was handled, false if the IOHandler + // should continue to try handle the interrupt itself. + //------------------------------------------------------------------ + virtual bool + IOHandlerInterrupt (IOHandler &io_handler) + { + return false; + } protected: Completion m_completion; // Support for common builtin completions bool m_io_handler_done; @@ -338,7 +349,7 @@ namespace lldb_private { } virtual ConstString - GetControlSequence (char ch) + IOHandlerGetControlSequence (char ch) { if (ch == 'd') return ConstString (m_end_line + "\n"); @@ -364,7 +375,9 @@ namespace lldb_private { // The last line was edited, if this line is empty, then we are done // getting our multiple lines. if (lines[line_idx] == m_end_line) + { return LineStatus::Done; + } } return LineStatus::Success; } @@ -380,6 +393,7 @@ namespace lldb_private { const char *editline_name, // Used for saving history files const char *prompt, bool multi_line, + uint32_t line_number_start, // If non-zero show line numbers starting at 'line_number_start' IOHandlerDelegate &delegate); IOHandlerEditline (Debugger &debugger, @@ -390,6 +404,7 @@ namespace lldb_private { const char *editline_name, // Used for saving history files const char *prompt, bool multi_line, + uint32_t line_number_start, // If non-zero show line numbers starting at 'line_number_start' IOHandlerDelegate &delegate); virtual @@ -407,7 +422,7 @@ namespace lldb_private { virtual void Cancel (); - virtual void + virtual bool Interrupt (); virtual void @@ -423,7 +438,7 @@ namespace lldb_private { virtual ConstString GetControlSequence (char ch) { - return m_delegate.GetControlSequence (ch); + return m_delegate.IOHandlerGetControlSequence (ch); } virtual const char * @@ -433,11 +448,14 @@ namespace lldb_private { SetPrompt (const char *prompt); bool - GetLine (std::string &line); + GetLine (std::string &line, bool &interrupted); bool - GetLines (StringList &lines); - + GetLines (StringList &lines, bool &interrupted); + + void + SetBaseLineNumber (uint32_t line); + private: static LineStatus LineCompletedCallback (Editline *editline, @@ -458,6 +476,7 @@ namespace lldb_private { std::unique_ptr m_editline_ap; IOHandlerDelegate &m_delegate; std::string m_prompt; + uint32_t m_base_line_number; // If non-zero, then show line numbers in prompt bool m_multi_line; }; @@ -517,7 +536,7 @@ namespace lldb_private { virtual void Cancel (); - virtual void + virtual bool Interrupt (); virtual void @@ -551,8 +570,8 @@ namespace lldb_private { virtual void Refresh (); - virtual void - Interrupt (); + virtual bool + HandleInterrupt (); virtual void GotEOF(); diff --git a/include/lldb/Core/Listener.h b/include/lldb/Core/Listener.h index a12a65d705db..2dbd2eb436ce 100644 --- a/include/lldb/Core/Listener.h +++ b/include/lldb/Core/Listener.h @@ -76,7 +76,7 @@ public: StopListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask); - // Returns true if an event was recieved, false if we timed out. + // Returns true if an event was received, false if we timed out. bool WaitForEvent (const TimeValue *timeout, lldb::EventSP &event_sp); diff --git a/include/lldb/Core/Mangled.h b/include/lldb/Core/Mangled.h index 8732dc00270c..7dc0eca3e8db 100644 --- a/include/lldb/Core/Mangled.h +++ b/include/lldb/Core/Mangled.h @@ -153,7 +153,7 @@ public: /// demangled name to be computed currently (we don't use the accessor). /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. //---------------------------------------------------------------------- void Dump (Stream *s) const; @@ -162,7 +162,7 @@ public: /// Dump a debug description of this object to a Stream \a s. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. //---------------------------------------------------------------------- void DumpDebug (Stream *s) const; @@ -219,7 +219,7 @@ public: /// Which name would you prefer to get? /// /// @return - /// A const reference to the the preferred name string object if this + /// A const reference to the preferred name string object if this /// object has a valid name of that kind, else a const reference to the /// other name is returned. //---------------------------------------------------------------------- diff --git a/include/lldb/Core/Module.h b/include/lldb/Core/Module.h index 56650582791b..bfde7cbc5db9 100644 --- a/include/lldb/Core/Module.h +++ b/include/lldb/Core/Module.h @@ -68,7 +68,7 @@ public: /// use ModuleList::GetSharedModule(). /// /// @param[in] file_spec - /// The file specification for the on disk repesentation of + /// The file specification for the on disk representation of /// this executable image. /// /// @param[in] arch @@ -88,10 +88,14 @@ public: Module (const FileSpec& file_spec, const ArchSpec& arch, const ConstString *object_name = NULL, - off_t object_offset = 0, + lldb::offset_t object_offset = 0, const TimeValue *object_mod_time_ptr = NULL); Module (const ModuleSpec &module_spec); + + static lldb::ModuleSP + CreateJITModule (const lldb::ObjectFileJITDelegateSP &delegate_sp); + //------------------------------------------------------------------ /// Destructor. //------------------------------------------------------------------ @@ -193,7 +197,7 @@ public: /// in a module. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. //------------------------------------------------------------------ void Dump (Stream *s); @@ -415,7 +419,7 @@ public: VariableList& variable_list); //------------------------------------------------------------------ - /// Find global and static variables by regular exression. + /// Find global and static variables by regular expression. /// /// @param[in] regex /// A regular expression to use when matching the name. @@ -468,11 +472,11 @@ public: /// /// @param[in] type_name /// The name of the type we are looking for that is a fully - /// or partially qualfieid type name. + /// or partially qualified type name. /// /// @param[in] exact_match - /// If \b true, \a type_name is fully qualifed and must match - /// exactly. If \b false, \a type_name is a partially qualfied + /// If \b true, \a type_name is fully qualified and must match + /// exactly. If \b false, \a type_name is a partially qualified /// name where the leading namespaces or classes can be /// omitted to make finding types that a user may type /// easier. @@ -700,14 +704,40 @@ public: virtual SectionList * GetSectionList (); + //------------------------------------------------------------------ + /// Notify the module that the file addresses for the Sections have + /// been updated. + /// + /// If the Section file addresses for a module are updated, this + /// method should be called. Any parts of the module, object file, + /// or symbol file that has cached those file addresses must invalidate + /// or update its cache. + //------------------------------------------------------------------ + virtual void + SectionFileAddressesChanged (); + uint32_t GetVersion (uint32_t *versions, uint32_t num_versions); - // Load an object file from memory. + //------------------------------------------------------------------ + /// Load an object file from memory. + /// + /// If available, the size of the object file in memory may be + /// passed to avoid additional round trips to process memory. + /// If the size is not provided, a default value is used. This + /// value should be large enough to enable the ObjectFile plugins + /// to read the header of the object file without going back to the + /// process. + /// + /// @return + /// The object file loaded from memory or NULL, if the operation + /// failed (see the `error` for more information in that case). + //------------------------------------------------------------------ ObjectFile * GetMemoryObjectFile (const lldb::ProcessSP &process_sp, lldb::addr_t header_addr, - Error &error); + Error &error, + size_t size_to_read = 512); //------------------------------------------------------------------ /// Get the symbol vendor interface for the current architecture. /// @@ -755,12 +785,12 @@ public: /// A debugging function that will cause everything in a module to /// be parsed. /// - /// All compile units will be pasred, along with all globals and + /// All compile units will be parsed, along with all globals and /// static variables and all functions for those compile units. /// All types, scopes, local variables, static variables, global /// variables, and line tables will be parsed. This can be used /// prior to dumping a module to see a complete list of the - /// resuling debug information that gets parsed, or as a debug + /// resulting debug information that gets parsed, or as a debug /// function to ensure that the module can consume all of the /// debug data the symbol vendor provides. //------------------------------------------------------------------ @@ -948,7 +978,7 @@ public: //------------------------------------------------------------------ // Return true if the file backing this module has changed since the - // module was originally created since we saved the intial file + // module was originally created since we saved the initial file // modification time when the module first gets created. //------------------------------------------------------------------ bool @@ -1156,7 +1186,9 @@ protected: friend class SymbolFile; private: - + + Module (); // Only used internally by CreateJITModule () + size_t FindTypes_Impl (const SymbolContext& sc, const ConstString &name, diff --git a/include/lldb/Core/ModuleList.h b/include/lldb/Core/ModuleList.h index f03f79fb00ce..c3074d4d6510 100644 --- a/include/lldb/Core/ModuleList.h +++ b/include/lldb/Core/ModuleList.h @@ -15,6 +15,7 @@ #include "lldb/lldb-private.h" #include "lldb/Host/Mutex.h" +#include "lldb/Utility/Iterable.h" namespace lldb_private { @@ -137,7 +138,7 @@ public: /// /// Clears the list of modules and releases a reference to each /// module object and if the reference count goes to zero, the - /// module will be deleted. Also relese all memory that might be + /// module will be deleted. Also release all memory that might be /// held by any collection classes (like std::vector) //------------------------------------------------------------------ void @@ -149,7 +150,7 @@ public: /// the supplied stream \a s. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. /// /// @see Module::Dump(Stream *) const //------------------------------------------------------------------ @@ -307,7 +308,7 @@ public: VariableList& variable_list) const; //------------------------------------------------------------------ - /// Find global and static variables by regular exression. + /// Find global and static variables by regular expression. /// /// @param[in] regex /// A regular expression to use when matching the name. @@ -577,6 +578,14 @@ protected: Notifier* m_notifier; +public: + typedef LockingAdaptedIterable ModuleIterable; + ModuleIterable + Modules() + { + return ModuleIterable(m_modules, GetMutex()); + } + }; } // namespace lldb_private diff --git a/include/lldb/Core/ModuleSpec.h b/include/lldb/Core/ModuleSpec.h index dfeb7b73ca37..195fd991f8de 100644 --- a/include/lldb/Core/ModuleSpec.h +++ b/include/lldb/Core/ModuleSpec.h @@ -370,7 +370,6 @@ public: if (dumped_something) strm.PutCString(", "); strm.Printf("object_mod_time = 0x%" PRIx64, m_object_mod_time.GetAsSecondsSinceJan1_1970()); - dumped_something = true; } } @@ -387,14 +386,15 @@ public: if (!FileSpec::Equal(fspec, GetFileSpec(), fspec.GetDirectory().IsEmpty() == false)) return false; } - if (match_module_spec.GetPlatformFileSpecPtr()) + if (GetPlatformFileSpec() && match_module_spec.GetPlatformFileSpecPtr()) { const FileSpec &fspec = match_module_spec.GetPlatformFileSpec(); if (!FileSpec::Equal(fspec, GetPlatformFileSpec(), fspec.GetDirectory().IsEmpty() == false)) return false; } - if (match_module_spec.GetSymbolFileSpecPtr()) + // Only match the symbol file spec if there is one in this ModuleSpec + if (GetSymbolFileSpec() && match_module_spec.GetSymbolFileSpecPtr()) { const FileSpec &fspec = match_module_spec.GetSymbolFileSpec(); if (!FileSpec::Equal(fspec, GetSymbolFileSpec(), fspec.GetDirectory().IsEmpty() == false)) diff --git a/include/lldb/Core/PluginManager.h b/include/lldb/Core/PluginManager.h index e02f43f4fa8b..a2ac67bf9f25 100644 --- a/include/lldb/Core/PluginManager.h +++ b/include/lldb/Core/PluginManager.h @@ -79,6 +79,24 @@ public: static DynamicLoaderCreateInstance GetDynamicLoaderCreateCallbackForPluginName (const ConstString &name); + //------------------------------------------------------------------ + // JITLoader + //------------------------------------------------------------------ + static bool + RegisterPlugin (const ConstString &name, + const char *description, + JITLoaderCreateInstance create_callback, + DebuggerInitializeCallback debugger_init_callback = NULL); + + static bool + UnregisterPlugin (JITLoaderCreateInstance create_callback); + + static JITLoaderCreateInstance + GetJITLoaderCreateCallbackAtIndex (uint32_t idx); + + static JITLoaderCreateInstance + GetJITLoaderCreateCallbackForPluginName (const ConstString &name); + //------------------------------------------------------------------ // EmulateInstruction //------------------------------------------------------------------ @@ -157,7 +175,8 @@ public: const char *description, ObjectFileCreateInstance create_callback, ObjectFileCreateMemoryInstance create_memory_callback, - ObjectFileGetModuleSpecifications get_module_specifications); + ObjectFileGetModuleSpecifications get_module_specifications, + ObjectFileSaveCore save_core = NULL); static bool UnregisterPlugin (ObjectFileCreateInstance create_callback); @@ -177,6 +196,8 @@ public: static ObjectFileCreateMemoryInstance GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name); + static Error + SaveCore (const lldb::ProcessSP &process_sp, const FileSpec &outfile); //------------------------------------------------------------------ // ObjectContainer diff --git a/include/lldb/Core/RegisterValue.h b/include/lldb/Core/RegisterValue.h index cf29cea46d36..1b1a71a11c5a 100644 --- a/include/lldb/Core/RegisterValue.h +++ b/include/lldb/Core/RegisterValue.h @@ -374,6 +374,12 @@ namespace lldb_private { uint32_t GetByteSize () const; + static uint32_t + GetMaxByteSize () + { + return kMaxRegisterByteSize; + } + void Clear(); diff --git a/include/lldb/Core/RegularExpression.h b/include/lldb/Core/RegularExpression.h index c116d439b94a..8e36811fa750 100644 --- a/include/lldb/Core/RegularExpression.h +++ b/include/lldb/Core/RegularExpression.h @@ -119,7 +119,7 @@ public: RegularExpression (); //------------------------------------------------------------------ - /// Constructor that takes a regulare expression with flags. + /// 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. @@ -129,7 +129,7 @@ public: /// compile. /// /// @param[in] flags - /// Flags that are passed the the \c regcomp() function. + /// Flags that are passed to the \c regcomp() function. //------------------------------------------------------------------ explicit RegularExpression (const char* re, int flags); @@ -141,7 +141,7 @@ public: //------------------------------------------------------------------ /// Destructor. /// - /// Any previosuly compiled regular expression contained in this + /// Any previously compiled regular expression contained in this /// object will be freed. //------------------------------------------------------------------ ~RegularExpression (); @@ -154,10 +154,10 @@ public: /// Compile a regular expression. /// /// Compile a regular expression using the supplied regular - /// expression text and flags. The compied regular expression lives + /// expression text and flags. 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 previosuly compiled regular + /// expression is compiled. Any previously compiled regular /// expression contained in this object will be freed. /// /// @param[in] re @@ -165,7 +165,7 @@ public: /// expression to compile. /// /// @param[in] flags - /// Flags that are passed the the \c regcomp() function. + /// Flags that are passed to the \c regcomp() function. /// /// @return /// \b true if the regular expression compiles successfully, diff --git a/include/lldb/Core/Section.h b/include/lldb/Core/Section.h index 437eaf59b9c4..32dac5f35b84 100644 --- a/include/lldb/Core/Section.h +++ b/include/lldb/Core/Section.h @@ -119,6 +119,7 @@ public: lldb::addr_t vm_size, lldb::offset_t file_offset, lldb::offset_t file_size, + uint32_t log2align, uint32_t flags); // Create a section that is a child of parent_section_sp @@ -132,6 +133,7 @@ public: lldb::addr_t vm_size, lldb::offset_t file_offset, lldb::offset_t file_size, + uint32_t log2align, uint32_t flags); ~Section (); @@ -284,6 +286,17 @@ public: return m_obj_file; } + uint32_t GetLog2Align() + { + return m_log2align; + } + + void + SetLog2Align(uint32_t align) + { + m_log2align = align; + } + protected: @@ -296,6 +309,7 @@ protected: lldb::addr_t m_byte_size; // Size in bytes that this section will occupy in memory at runtime lldb::offset_t m_file_offset; // Object file offset (if any) lldb::offset_t m_file_size; // Object file size (can be smaller than m_byte_size for zero filled sections...) + uint32_t m_log2align; // log_2(align) of the section (i.e. section has to be aligned to 2^m_log2align) SectionList m_children; // Child sections bool m_fake:1, // If true, then this section only can contain the address if one of its // children contains an address. This allows for gaps between the children diff --git a/include/lldb/Core/SourceManager.h b/include/lldb/Core/SourceManager.h index d8c9eccd3477..0f65be1bee4b 100644 --- a/include/lldb/Core/SourceManager.h +++ b/include/lldb/Core/SourceManager.h @@ -85,7 +85,7 @@ public: CalculateLineOffsets (uint32_t line = UINT32_MAX); FileSpec m_file_spec_orig; // The original file spec that was used (can be different from m_file_spec) - FileSpec m_file_spec; // The actualy file spec being used (if the target has source mappings, this might be different from m_file_spec_orig) + FileSpec m_file_spec; // The actually file spec being used (if the target has source mappings, this might be different from m_file_spec_orig) TimeValue m_mod_time; // Keep the modification time that this file data is valid for uint32_t m_source_map_mod_id; // If the target uses path remappings, be sure to clear our notion of a source file if the path modification ID changes lldb::DataBufferSP m_data_sp; diff --git a/include/lldb/Core/Stream.h b/include/lldb/Core/Stream.h index 0fd4aac041a9..11780aa6ff0f 100644 --- a/include/lldb/Core/Stream.h +++ b/include/lldb/Core/Stream.h @@ -472,7 +472,7 @@ public: /// Indent the current line in the stream. /// /// Indent the current line using the current indentation level and - /// print an optional string following the idenatation spaces. + /// print an optional string following the indentation spaces. /// /// @param[in] s /// A C string to print following the indentation. If NULL, just diff --git a/include/lldb/Core/StructuredData.h b/include/lldb/Core/StructuredData.h new file mode 100644 index 000000000000..a4cabf4fe352 --- /dev/null +++ b/include/lldb/Core/StructuredData.h @@ -0,0 +1,486 @@ +//===-- StructuredData.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_StructuredData_h_ +#define liblldb_StructuredData_h_ + +// C Includes +// C++ Includes + +#include +#include +#include +#include + +#include "llvm/ADT/StringRef.h" + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-defines.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/Stream.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class StructuredData StructuredData.h "lldb/Core/StructuredData.h" +/// @brief A class which can hold structured data +/// +/// The StructuredData class is designed to hold the data from a JSON +/// or plist style file -- a serialized data structure with dictionaries +/// (maps, hashes), arrays, and concrete values like integers, floating +/// point numbers, strings, booleans. +/// +/// StructuredData does not presuppose any knowledge of the schema for +/// the data it is holding; it can parse JSON data, for instance, and +/// other parts of lldb can iterate through the parsed data set to find +/// keys and values that may be present. +//---------------------------------------------------------------------- + +class StructuredData +{ +public: + + class Object; + class Array; + class Integer; + class Float; + class Boolean; + class String; + class Dictionary; + + typedef std::shared_ptr ObjectSP; + typedef std::shared_ptr ArraySP; + typedef std::shared_ptr DictionarySP; + + enum class Type { + eTypeInvalid = -1, + eTypeNull = 0, + eTypeArray, + eTypeInteger, + eTypeFloat, + eTypeBoolean, + eTypeString, + eTypeDictionary + }; + + class Object : + public std::enable_shared_from_this + { + public: + + Object (Type t = Type::eTypeInvalid) : + m_type (t) + { + } + + virtual ~Object () + { + } + + virtual void + Clear () + { + m_type = Type::eTypeInvalid; + } + + Type + GetType () const + { + return m_type; + } + + void + SetType (Type t) + { + m_type = t; + } + + Array * + GetAsArray () + { + if (m_type == Type::eTypeArray) + return (Array *)this; + return NULL; + } + + Dictionary * + GetAsDictionary () + { + if (m_type == Type::eTypeDictionary) + return (Dictionary *)this; + return NULL; + } + + Integer * + GetAsInteger () + { + if (m_type == Type::eTypeInteger) + return (Integer *)this; + return NULL; + } + + Float * + GetAsFloat () + { + if (m_type == Type::eTypeFloat) + return (Float *)this; + return NULL; + } + + Boolean * + GetAsBoolean () + { + if (m_type == Type::eTypeBoolean) + return (Boolean *)this; + return NULL; + } + + String * + GetAsString () + { + if (m_type == Type::eTypeString) + return (String *)this; + return NULL; + } + + ObjectSP + GetObjectForDotSeparatedPath (llvm::StringRef path); + + virtual void + Dump (Stream &s) const = 0; + + private: + Type m_type; + }; + + class Array : public Object + { + public: + Array () : + Object (Type::eTypeArray) + { + } + + virtual + ~Array() + { + } + + size_t + GetSize() + { + return m_items.size(); + } + + ObjectSP + operator[](size_t idx) + { + if (idx < m_items.size()) + return m_items[idx]; + return ObjectSP(); + } + + ObjectSP + GetItemAtIndex (size_t idx) + { + if (idx < m_items.size()) + return m_items[idx]; + return ObjectSP(); + } + + void + Push(ObjectSP item) + { + m_items.push_back(item); + } + + void + AddItem(ObjectSP item) + { + m_items.push_back(item); + } + + virtual void + Dump (Stream &s) const; + + protected: + typedef std::vector collection; + collection m_items; + }; + + + class Integer : public Object + { + public: + Integer () : + Object (Type::eTypeInteger), + m_value () + { + } + + virtual ~Integer() + { + } + + void + SetValue (uint64_t value) + { + m_value = value; + } + + uint64_t + GetValue () + { + return m_value; + } + + virtual void + Dump (Stream &s) const; + + protected: + uint64_t m_value; + }; + + class Float : public Object + { + public: + Float () : + Object (Type::eTypeFloat), + m_value () + { + } + + virtual ~Float() + { + } + + void + SetValue (double value) + { + m_value = value; + } + + double + GetValue () + { + return m_value; + } + + virtual void + Dump (Stream &s) const; + + protected: + double m_value; + }; + + class Boolean : public Object + { + public: + Boolean () : + Object (Type::eTypeBoolean), + m_value () + { + } + + virtual ~Boolean() + { + } + + void + SetValue (bool value) + { + m_value = value; + } + + bool + GetValue () + { + return m_value; + } + + virtual void + Dump (Stream &s) const; + + protected: + bool m_value; + }; + + + + class String : public Object + { + public: + String () : + Object (Type::eTypeString), + m_value () + { + } + + void + SetValue (std::string string) + { + m_value = string; + } + + std::string + GetValue () + { + return m_value; + } + + virtual void + Dump (Stream &s) const; + + protected: + std::string m_value; + }; + + class Dictionary : public Object + { + public: + Dictionary () : + Object (Type::eTypeDictionary), + m_dict () + { + } + + virtual ~Dictionary() + { + } + size_t + GetSize() + { + return m_dict.size(); + } + + ObjectSP + GetKeys() + { + ObjectSP object_sp(new Array ()); + Array *array = object_sp->GetAsArray(); + collection::const_iterator iter; + for (iter = m_dict.begin(); iter != m_dict.end(); ++iter) + { + ObjectSP key_object_sp(new String()); + key_object_sp->GetAsString()->SetValue(iter->first.AsCString()); + array->Push(key_object_sp); + } + return object_sp; + } + + ObjectSP + GetValueForKey (const char *key) + { + ObjectSP value_sp; + if (key) + { + ConstString key_cs(key); + for (collection::const_iterator iter = m_dict.begin(); iter != m_dict.end(); ++iter) + { + if (key_cs == iter->first) + { + value_sp = iter->second; + break; + } + } + } + return value_sp; + } + + bool + HasKey (const char *key) + { + ConstString key_cs (key); + collection::const_iterator search = m_dict.find(key_cs); + if (search != m_dict.end()) + { + return true; + } + else + { + return false; + } + } + + void + AddItem (const char *key, ObjectSP value) + { + ConstString key_cs(key); + m_dict[key_cs] = value; + } + + void + AddIntegerItem (const char *key, uint64_t value) + { + ObjectSP val_obj (new Integer()); + val_obj->GetAsInteger()->SetValue (value); + AddItem (key, val_obj); + } + + void + AddFloatItem (const char *key, double value) + { + ObjectSP val_obj (new Float()); + val_obj->GetAsFloat()->SetValue (value); + AddItem (key, val_obj); + } + + void + AddStringItem (const char *key, std::string value) + { + ObjectSP val_obj (new String()); + val_obj->GetAsString()->SetValue (value); + AddItem (key, val_obj); + } + + void + AddBooleanItem (const char *key, bool value) + { + ObjectSP val_obj (new Boolean()); + val_obj->GetAsBoolean()->SetValue (value); + AddItem (key, val_obj); + } + + virtual void + Dump (Stream &s) const; + + protected: + typedef std::map collection; + collection m_dict; + }; + + class Null : public Object + { + public: + Null () : + Object (Type::eTypeNull) + { + } + + virtual ~Null() + { + } + + virtual void + Dump (Stream &s) const; + + protected: + }; + + + static ObjectSP + ParseJSON (std::string json_text); + +}; // class StructuredData + + +} // namespace lldb_private + +#endif // liblldb_StructuredData_h_ diff --git a/include/lldb/Core/UserID.h b/include/lldb/Core/UserID.h index ea6af74759bf..230e43fa551f 100644 --- a/include/lldb/Core/UserID.h +++ b/include/lldb/Core/UserID.h @@ -19,12 +19,12 @@ namespace lldb_private { /// @class UserID UserID.h "lldb/Core/UserID.h" /// @brief A mix in class that contains a generic user ID. /// -/// UserID is desinged as a mix in class that can contain an integer -/// based unique identifier for a varietly of objects in lldb. +/// UserID is designed as a mix in class that can contain an integer +/// based unique identifier for a variety of objects in lldb. /// /// The value for this identifier is chosen by each parser plug-in. A /// value should be chosen that makes sense for each kind of object -/// should and allows quick access to further and more in depth parsing. +/// and should allow quick access to further and more in depth parsing. /// /// Symbol table entries can use this to store the original symbol table /// index, functions can use it to store the symbol table index or the diff --git a/include/lldb/Core/Value.h b/include/lldb/Core/Value.h index c7d44322333c..957cedeb0dcc 100644 --- a/include/lldb/Core/Value.h +++ b/include/lldb/Core/Value.h @@ -124,9 +124,15 @@ public: Value(); Value(const Scalar& scalar); Value(const Vector& vector); - Value(const uint8_t *bytes, int len); + Value(const void *bytes, int len); Value(const Value &rhs); + void + SetBytes (const void *bytes, int len); + + void + AppendBytes (const void *bytes, int len); + Value & operator=(const Value &rhs); @@ -232,8 +238,23 @@ public: return false; } - void + size_t ResizeData(size_t len); + + size_t + AppendDataToHostBuffer (const Value &rhs); + + DataBufferHeap & + GetBuffer () + { + return m_data_buffer; + } + + const DataBufferHeap & + GetBuffer () const + { + return m_data_buffer; + } bool ValueOf(ExecutionContext *exe_ctx); diff --git a/include/lldb/Core/ValueObject.h b/include/lldb/Core/ValueObject.h index e2847c778484..6a08ec6507f9 100644 --- a/include/lldb/Core/ValueObject.h +++ b/include/lldb/Core/ValueObject.h @@ -35,7 +35,7 @@ namespace lldb_private { /// ValueObject: /// /// This abstract class provides an interface to a particular value, be it a register, a local or global variable, -/// that is evaluated in some particular scope. The ValueObject also has the capibility of being the "child" of +/// that is evaluated in some particular scope. The ValueObject also has the capability of being the "child" of /// some other variable object, and in turn of having children. /// If a ValueObject is a root variable object - having no parent - then it must be constructed with respect to some /// particular ExecutionContextScope. If it is a child, it inherits the ExecutionContextScope from its parent. @@ -380,7 +380,7 @@ public: GetTypeImpl (); //------------------------------------------------------------------ - // Sublasses must implement the functions below. + // Subclasses must implement the functions below. //------------------------------------------------------------------ virtual uint64_t GetByteSize() = 0; @@ -389,11 +389,14 @@ public: GetValueType() const = 0; //------------------------------------------------------------------ - // Sublasses can implement the functions below. + // Subclasses can implement the functions below. //------------------------------------------------------------------ virtual ConstString GetTypeName(); + virtual ConstString + GetDisplayTypeName(); + virtual ConstString GetQualifiedTypeName(); @@ -427,6 +430,9 @@ public: return false; } + bool + IsBaseClass (uint32_t& depth); + virtual bool IsDereferenceOfParent () { @@ -465,7 +471,7 @@ public: return true; } - virtual off_t + virtual lldb::offset_t GetByteOffset() { return 0; @@ -528,7 +534,7 @@ public: GetDeclaration (Declaration &decl); //------------------------------------------------------------------ - // The functions below should NOT be modified by sublasses + // The functions below should NOT be modified by subclasses //------------------------------------------------------------------ const Error & GetError(); @@ -670,6 +676,9 @@ public: virtual lldb::ValueObjectSP GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create); + virtual lldb::ValueObjectSP + GetSyntheticBase (uint32_t offset, const ClangASTType& type, bool can_create); + virtual lldb::ValueObjectSP GetDynamicValue (lldb::DynamicValueType valueType); @@ -712,6 +721,10 @@ public: { } + // Find the address of the C++ vtable pointer + virtual lldb::addr_t + GetCPPVTableAddress(AddressType &address_type); + virtual lldb::ValueObjectSP Cast (const ClangASTType &clang_ast_type); @@ -762,7 +775,7 @@ public: static lldb::ValueObjectSP CreateValueObjectFromData (const char* name, - DataExtractor& data, + const DataExtractor& data, const ExecutionContext& exe_ctx, ClangASTType type); @@ -793,7 +806,7 @@ public: uint32_t item_count = 1); virtual uint64_t - GetData (DataExtractor& data); + GetData (DataExtractor& data, Error &error); virtual bool SetData (DataExtractor &data, Error &error); @@ -961,7 +974,7 @@ protected: void SetChildrenCount (size_t count) { - m_children_count = count; + Clear(count); } size_t @@ -971,10 +984,10 @@ protected: } void - Clear() + Clear(size_t new_count = 0) { - m_children_count = 0; Mutex::Locker locker(m_mutex); + m_children_count = new_count; m_children.clear(); } @@ -1127,7 +1140,7 @@ protected: ClearDynamicTypeInformation (); //------------------------------------------------------------------ - // Sublasses must implement the functions below. + // Subclasses must implement the functions below. //------------------------------------------------------------------ virtual ClangASTType diff --git a/include/lldb/Core/ValueObjectChild.h b/include/lldb/Core/ValueObjectChild.h index 780529a4af11..07d1f294bd80 100644 --- a/include/lldb/Core/ValueObjectChild.h +++ b/include/lldb/Core/ValueObjectChild.h @@ -32,7 +32,7 @@ public: return m_byte_size; } - virtual off_t + virtual lldb::offset_t GetByteOffset() { return m_byte_offset; @@ -62,6 +62,9 @@ public: virtual ConstString GetQualifiedTypeName(); + virtual ConstString + GetDisplayTypeName(); + virtual bool IsInScope (); diff --git a/include/lldb/Core/ValueObjectConstResult.h b/include/lldb/Core/ValueObjectConstResult.h index 4964d0589a09..dd87fc848ae8 100644 --- a/include/lldb/Core/ValueObjectConstResult.h +++ b/include/lldb/Core/ValueObjectConstResult.h @@ -80,6 +80,9 @@ public: virtual ConstString GetTypeName(); + virtual ConstString + GetDisplayTypeName(); + virtual bool IsInScope (); diff --git a/include/lldb/Core/ValueObjectDynamicValue.h b/include/lldb/Core/ValueObjectDynamicValue.h index 68f88c96e545..7607bd38137d 100644 --- a/include/lldb/Core/ValueObjectDynamicValue.h +++ b/include/lldb/Core/ValueObjectDynamicValue.h @@ -37,6 +37,9 @@ public: virtual ConstString GetQualifiedTypeName(); + + virtual ConstString + GetDisplayTypeName(); virtual size_t CalculateNumChildren(); diff --git a/include/lldb/Core/ValueObjectMemory.h b/include/lldb/Core/ValueObjectMemory.h index 627d73eb4b27..41b43188a46a 100644 --- a/include/lldb/Core/ValueObjectMemory.h +++ b/include/lldb/Core/ValueObjectMemory.h @@ -47,6 +47,9 @@ public: virtual ConstString GetTypeName(); + virtual ConstString + GetDisplayTypeName(); + virtual size_t CalculateNumChildren(); diff --git a/include/lldb/Core/ValueObjectRegister.h b/include/lldb/Core/ValueObjectRegister.h index 6820629f08e1..f7c7683d60bc 100644 --- a/include/lldb/Core/ValueObjectRegister.h +++ b/include/lldb/Core/ValueObjectRegister.h @@ -45,6 +45,9 @@ public: virtual ConstString GetQualifiedTypeName(); + + virtual ConstString + GetDisplayTypeName(); virtual size_t CalculateNumChildren(); diff --git a/include/lldb/Core/ValueObjectSyntheticFilter.h b/include/lldb/Core/ValueObjectSyntheticFilter.h index f1d8c885c255..e12698f49bb1 100644 --- a/include/lldb/Core/ValueObjectSyntheticFilter.h +++ b/include/lldb/Core/ValueObjectSyntheticFilter.h @@ -41,6 +41,9 @@ public: virtual ConstString GetQualifiedTypeName(); + + virtual ConstString + GetDisplayTypeName(); virtual bool MightHaveChildren(); diff --git a/include/lldb/Core/ValueObjectVariable.h b/include/lldb/Core/ValueObjectVariable.h index 8a30b00f6bbd..0e32d09057dc 100644 --- a/include/lldb/Core/ValueObjectVariable.h +++ b/include/lldb/Core/ValueObjectVariable.h @@ -39,6 +39,9 @@ public: virtual ConstString GetQualifiedTypeName(); + + virtual ConstString + GetDisplayTypeName(); virtual size_t CalculateNumChildren(); diff --git a/include/lldb/Core/dwarf.h b/include/lldb/Core/dwarf.h index 91c8dfb9d0da..9fa8816229a9 100644 --- a/include/lldb/Core/dwarf.h +++ b/include/lldb/Core/dwarf.h @@ -12,7 +12,7 @@ #include -// Get the DWARF constant defintions from llvm +// Get the DWARF constant definitions from llvm #include "llvm/Support/Dwarf.h" // and stuff them in our default namespace using namespace llvm::dwarf; diff --git a/include/lldb/DataFormatters/CXXFormatterFunctions.h b/include/lldb/DataFormatters/CXXFormatterFunctions.h index c53ef9589eea..753ffa1bae1b 100644 --- a/include/lldb/DataFormatters/CXXFormatterFunctions.h +++ b/include/lldb/DataFormatters/CXXFormatterFunctions.h @@ -19,6 +19,7 @@ #include "lldb/DataFormatters/FormatClasses.h" #include "lldb/DataFormatters/TypeSynthetic.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Target.h" #include "clang/AST/ASTContext.h" @@ -26,6 +27,9 @@ namespace lldb_private { namespace formatters { + StackFrame* + GetViableFrame (ExecutionContext exe_ctx); + bool ExtractValueFromObjCExpression (ValueObject &valobj, const char* target_type, @@ -139,6 +143,9 @@ namespace lldb_private { bool NSStringSummaryProvider (ValueObject& valobj, Stream& stream); + bool + NSTaggedString_SummaryProvider (ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream& stream); + bool NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream); @@ -176,113 +183,6 @@ namespace lldb_private { extern template bool ObjCSELSummaryProvider (ValueObject&, Stream&); - class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - private: - struct DataDescriptor_32 - { - uint32_t _used; - uint32_t _priv1 : 2 ; - uint32_t _size : 30; - uint32_t _priv2 : 2; - uint32_t offset : 30; - uint32_t _priv3; - uint32_t _data; - }; - struct DataDescriptor_64 - { - uint64_t _used; - uint64_t _priv1 : 2 ; - uint64_t _size : 62; - uint64_t _priv2 : 2; - uint64_t offset : 62; - uint32_t _priv3; - uint64_t _data; - }; - public: - NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~NSArrayMSyntheticFrontEnd (); - private: - ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; - DataDescriptor_32 *m_data_32; - DataDescriptor_64 *m_data_64; - ClangASTType m_id_type; - std::vector m_children; - }; - - class NSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - public: - NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~NSArrayISyntheticFrontEnd (); - private: - ExecutionContextRef m_exe_ctx_ref; - uint8_t m_ptr_size; - uint64_t m_items; - lldb::addr_t m_data_ptr; - ClangASTType m_id_type; - std::vector m_children; - }; - - class NSArrayCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd - { - public: - NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); - - virtual size_t - CalculateNumChildren (); - - virtual lldb::ValueObjectSP - GetChildAtIndex (size_t idx); - - virtual bool - Update(); - - virtual bool - MightHaveChildren (); - - virtual size_t - GetIndexOfChildWithName (const ConstString &name); - - virtual - ~NSArrayCodeRunningSyntheticFrontEnd (); - }; - SyntheticChildrenFrontEnd* NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); class NSDictionaryISyntheticFrontEnd : public SyntheticChildrenFrontEnd diff --git a/include/lldb/DataFormatters/FormatManager.h b/include/lldb/DataFormatters/FormatManager.h index 24ec877ee515..0b9144dffa17 100644 --- a/include/lldb/DataFormatters/FormatManager.h +++ b/include/lldb/DataFormatters/FormatManager.h @@ -25,6 +25,7 @@ #include "lldb/DataFormatters/TypeCategoryMap.h" #include +#include namespace lldb_private { @@ -39,6 +40,14 @@ class FormatManager : public IFormatChangeListener typedef TypeCategoryMap::MapType::iterator CategoryMapIterator; public: + template + using HardcodedFormatterFinder = std::function; + + template + using HardcodedFormatterFinders = std::vector>; + typedef TypeCategoryMap::CallbackType CategoryCallback; FormatManager (); @@ -260,6 +269,19 @@ private: ConstString m_vectortypes_category_name; ConstString m_appkit_category_name; + HardcodedFormatterFinders m_hardcoded_formats; + HardcodedFormatterFinders m_hardcoded_summaries; + HardcodedFormatterFinders m_hardcoded_synthetics; + + lldb::TypeFormatImplSP + GetHardcodedFormat (ValueObject&,lldb::DynamicValueType); + + lldb::TypeSummaryImplSP + GetHardcodedSummaryFormat (ValueObject&,lldb::DynamicValueType); + + lldb::SyntheticChildrenSP + GetHardcodedSyntheticChildren (ValueObject&,lldb::DynamicValueType); + TypeCategoryMap& GetCategories () { @@ -281,8 +303,11 @@ private: void LoadObjCFormatters (); + + void + LoadHardcodedFormatters (); }; } // namespace lldb_private - + #endif // lldb_FormatManager_h_ diff --git a/include/lldb/DataFormatters/TypeFormat.h b/include/lldb/DataFormatters/TypeFormat.h index 20fa8f2d4e7f..1090d7843e53 100644 --- a/include/lldb/DataFormatters/TypeFormat.h +++ b/include/lldb/DataFormatters/TypeFormat.h @@ -14,6 +14,7 @@ // C++ Includes #include +#include // Other libraries and framework includes @@ -135,7 +136,7 @@ namespace lldb_private { typedef std::shared_ptr SharedPointer; typedef bool(*ValueCallback)(void*, ConstString, const lldb::TypeFormatImplSP&); - virtual ~TypeFormatImpl () = default; + virtual ~TypeFormatImpl (); bool Cascades () const @@ -229,7 +230,7 @@ namespace lldb_private { typedef std::shared_ptr SharedPointer; typedef bool(*ValueCallback)(void*, ConstString, const TypeFormatImpl_Format::SharedPointer&); - virtual ~TypeFormatImpl_Format () = default; + virtual ~TypeFormatImpl_Format (); lldb::Format GetFormat () const @@ -272,7 +273,7 @@ namespace lldb_private { typedef std::shared_ptr SharedPointer; typedef bool(*ValueCallback)(void*, ConstString, const TypeFormatImpl_EnumType::SharedPointer&); - ~TypeFormatImpl_EnumType () = default; + ~TypeFormatImpl_EnumType (); ConstString GetTypeName () @@ -301,7 +302,7 @@ namespace lldb_private { protected: ConstString m_enum_type; - mutable std::map m_types; + mutable std::unordered_map m_types; private: DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl_EnumType); diff --git a/include/lldb/DataFormatters/TypeSummary.h b/include/lldb/DataFormatters/TypeSummary.h index 1c195ab2ba4d..699494336cc6 100644 --- a/include/lldb/DataFormatters/TypeSummary.h +++ b/include/lldb/DataFormatters/TypeSummary.h @@ -225,14 +225,14 @@ namespace lldb_private { return m_flags.GetSkipReferences(); } - bool - DoesPrintChildren () const + virtual bool + DoesPrintChildren (ValueObject* valobj) const { return !m_flags.GetDontShowChildren(); } - bool - DoesPrintValue () const + virtual bool + DoesPrintValue (ValueObject* valobj) const { return !m_flags.GetDontShowValue(); } @@ -243,8 +243,8 @@ namespace lldb_private { return m_flags.GetShowMembersOneLiner(); } - bool - HideNames () const + virtual bool + HideNames (ValueObject* valobj) const { return m_flags.GetHideItemNames(); } @@ -267,13 +267,13 @@ namespace lldb_private { m_flags.SetSkipReferences(value); } - void + virtual void SetDoesPrintChildren (bool value) { m_flags.SetDontShowChildren(!value); } - void + virtual void SetDoesPrintValue (bool value) { m_flags.SetDontShowValue(!value); @@ -285,7 +285,7 @@ namespace lldb_private { m_flags.SetShowMembersOneLiner(value); } - void + virtual void SetHideNames (bool value) { m_flags.SetHideItemNames(value); diff --git a/include/lldb/DataFormatters/ValueObjectPrinter.h b/include/lldb/DataFormatters/ValueObjectPrinter.h index 375bb50c876d..bfe2d9c402d3 100644 --- a/include/lldb/DataFormatters/ValueObjectPrinter.h +++ b/include/lldb/DataFormatters/ValueObjectPrinter.h @@ -386,7 +386,7 @@ private: std::string m_summary; std::string m_error; - friend class StringSummaryFormat; + friend struct StringSummaryFormat; DISALLOW_COPY_AND_ASSIGN(ValueObjectPrinter); }; diff --git a/include/lldb/Expression/ASTStructExtractor.h b/include/lldb/Expression/ASTStructExtractor.h index a1518de83d6d..9e467797a398 100644 --- a/include/lldb/Expression/ASTStructExtractor.h +++ b/include/lldb/Expression/ASTStructExtractor.h @@ -30,7 +30,7 @@ namespace lldb_private { /// /// The definition of this struct is itself in the body of the wrapper function, /// so Clang does the structure layout itself. ASTStructExtractor reads through -/// the AST for the wrapper funtion and finds the struct. +/// the AST for the wrapper function and finds the struct. //---------------------------------------------------------------------- class ASTStructExtractor : public clang::SemaConsumer { diff --git a/include/lldb/Expression/ClangExpressionDeclMap.h b/include/lldb/Expression/ClangExpressionDeclMap.h index b04e1bd6f116..8a4aa82b8727 100644 --- a/include/lldb/Expression/ClangExpressionDeclMap.h +++ b/include/lldb/Expression/ClangExpressionDeclMap.h @@ -167,7 +167,7 @@ public: const ConstString &name, llvm::Value *value, size_t size, - off_t alignment); + lldb::offset_t alignment); //------------------------------------------------------------------ /// [Used by IRForTarget] Finalize the struct, laying out the position @@ -198,7 +198,7 @@ public: bool GetStructInfo (uint32_t &num_elements, size_t &size, - off_t &alignment); + lldb::offset_t &alignment); //------------------------------------------------------------------ /// [Used by IRForTarget] Get specific information about one field @@ -234,7 +234,7 @@ public: bool GetStructElement (const clang::NamedDecl *&decl, llvm::Value *&value, - off_t &offset, + lldb::offset_t &offset, ConstString &name, uint32_t index); @@ -461,7 +461,7 @@ private: { } - off_t m_struct_alignment; ///< The alignment of the struct in bytes. + lldb::offset_t m_struct_alignment; ///< The alignment of the struct in bytes. size_t m_struct_size; ///< The size of the struct in bytes. bool m_struct_laid_out; ///< True if the struct has been laid out and the layout is valid (that is, no new fields have been added since). ConstString m_result_name; ///< The name of the result variable ($1, for example) diff --git a/include/lldb/Expression/ClangExpressionParser.h b/include/lldb/Expression/ClangExpressionParser.h index 3247f2094ba6..c79494d1a521 100644 --- a/include/lldb/Expression/ClangExpressionParser.h +++ b/include/lldb/Expression/ClangExpressionParser.h @@ -40,7 +40,7 @@ public: //------------------------------------------------------------------ /// Constructor /// - /// Initializes class variabes. + /// Initializes class variables. /// /// @param[in] exe_scope, /// If non-NULL, an execution context scope that can help to @@ -51,7 +51,8 @@ public: /// The expression to be parsed. //------------------------------------------------------------------ ClangExpressionParser (ExecutionContextScope *exe_scope, - ClangExpression &expr); + ClangExpression &expr, + bool generate_debug_info); //------------------------------------------------------------------ /// Destructor @@ -84,9 +85,9 @@ public: /// and func_end do not delimit an allocated region; the allocated /// region may begin before func_addr.) /// - /// @param[in] execution_unit_ap + /// @param[in] execution_unit_sp /// After parsing, ownership of the execution unit for - /// for the expression is handed to this unique pointer. + /// for the expression is handed to this shared pointer. /// /// @param[in] exe_ctx /// The execution context to write the function into. @@ -112,7 +113,7 @@ public: Error PrepareForExecution (lldb::addr_t &func_addr, lldb::addr_t &func_end, - std::unique_ptr &execution_unit_ap, + std::shared_ptr &execution_unit_sp, ExecutionContext &exe_ctx, bool &can_interpret, lldb_private::ExecutionPolicy execution_policy); @@ -134,6 +135,9 @@ public: DisassembleFunction (Stream &stream, ExecutionContext &exe_ctx); + bool + GetGenerateDebugInfo () const; + private: ClangExpression & m_expr; ///< The expression to be parsed std::unique_ptr m_llvm_context; ///< The LLVM context to generate IR into @@ -143,7 +147,6 @@ private: std::unique_ptr m_selector_table; ///< Selector table for Objective-C methods std::unique_ptr m_ast_context; ///< The AST context used to hold types and names for the parser std::unique_ptr m_code_generator; ///< The Clang object that generates IR - std::unique_ptr m_execution_unit; ///< The container for the finished Module }; } diff --git a/include/lldb/Expression/ClangExpressionVariable.h b/include/lldb/Expression/ClangExpressionVariable.h index 620e604fb18c..5ee7a3058946 100644 --- a/include/lldb/Expression/ClangExpressionVariable.h +++ b/include/lldb/Expression/ClangExpressionVariable.h @@ -162,9 +162,9 @@ public: { } - off_t m_alignment; ///< The required alignment of the variable, in bytes - size_t m_size; ///< The space required for the variable, in bytes - off_t m_offset; ///< The offset of the variable in the struct, in bytes + lldb::offset_t m_alignment; ///< The required alignment of the variable, in bytes + size_t m_size; ///< The space required for the variable, in bytes + lldb::offset_t m_offset; ///< The offset of the variable in the struct, in bytes }; private: @@ -237,8 +237,8 @@ public: // this function is used to copy the address-of m_live_sp into m_frozen_sp // this is necessary because the results of certain cast and pointer-arithmetic // operations (such as those described in bugzilla issues 11588 and 11618) generate - // frozen objcts that do not have a valid address-of, which can be troublesome when - // using synthetic children providers. transferring the address-of the live object + // frozen objects that do not have a valid address-of, which can be troublesome when + // using synthetic children providers. Transferring the address-of the live object // solves these issues and provides the expected user-level behavior void TransferAddress (bool force = false); diff --git a/include/lldb/Expression/ClangFunction.h b/include/lldb/Expression/ClangFunction.h index e150d389b416..61d56729f93d 100644 --- a/include/lldb/Expression/ClangFunction.h +++ b/include/lldb/Expression/ClangFunction.h @@ -88,7 +88,8 @@ public: ClangFunction (ExecutionContextScope &exe_scope, Function &function_ptr, ClangASTContext *ast_context, - const ValueList &arg_value_list); + const ValueList &arg_value_list, + const char *name); //------------------------------------------------------------------ /// Constructor @@ -114,7 +115,8 @@ public: ClangFunction (ExecutionContextScope &exe_scope, const ClangASTType &return_type, const Address& function_address, - const ValueList &arg_value_list); + const ValueList &arg_value_list, + const char *name); //------------------------------------------------------------------ /// Destructor @@ -251,9 +253,9 @@ public: /// The result value will be put here after running the function. /// /// @return - /// Returns one of the ExecutionResults enum indicating function call status. + /// Returns one of the ExpressionResults enum indicating function call status. //------------------------------------------------------------------ - ExecutionResults + lldb::ExpressionResults ExecuteFunction(ExecutionContext &exe_ctx, lldb::addr_t *args_addr_ptr, const EvaluateExpressionOptions &options, @@ -410,7 +412,9 @@ private: //------------------------------------------------------------------ std::unique_ptr m_parser; ///< The parser responsible for compiling the function. - std::unique_ptr m_execution_unit_ap; + std::shared_ptr m_execution_unit_sp; + lldb::ModuleWP m_jit_module_wp; + std::string m_name; ///< The name of this clang function - for debugging purposes. Function *m_function_ptr; ///< The function we're going to call. May be NULL if we don't have debug info for the function. Address m_function_addr; ///< If we don't have the FunctionSP, we at least need the address & return type. diff --git a/include/lldb/Expression/ClangUserExpression.h b/include/lldb/Expression/ClangUserExpression.h index 83fdf1c21955..9d2e9093c0bd 100644 --- a/include/lldb/Expression/ClangUserExpression.h +++ b/include/lldb/Expression/ClangUserExpression.h @@ -105,7 +105,8 @@ public: Parse (Stream &error_stream, ExecutionContext &exe_ctx, lldb_private::ExecutionPolicy execution_policy, - bool keep_result_in_memory); + bool keep_result_in_memory, + bool generate_debug_info); bool CanInterpret () @@ -143,7 +144,7 @@ public: /// @return /// A Process::Execution results value. //------------------------------------------------------------------ - ExecutionResults + lldb::ExpressionResults Execute (Stream &error_stream, ExecutionContext &exe_ctx, const EvaluateExpressionOptions& options, @@ -166,7 +167,7 @@ public: /// /// @param[in] function_stack_pointer /// A pointer to the base of the function's stack frame. This - /// is used to determine whether the expession result resides in + /// is used to determine whether the expression result resides in /// memory that will still be valid, or whether it needs to be /// treated as homeless for the purpose of future expressions. /// @@ -295,9 +296,9 @@ public: /// fails to parse, run, or evaluated. /// /// @result - /// A Process::ExecutionResults value. eExecutionCompleted for success. + /// A Process::ExpressionResults value. eExpressionCompleted for success. //------------------------------------------------------------------ - static ExecutionResults + static lldb::ExpressionResults Evaluate (ExecutionContext &exe_ctx, const EvaluateExpressionOptions& options, const char *expr_cstr, @@ -308,7 +309,7 @@ public: static const Error::ValueType kNoResult = 0x1001; ///< ValueObject::GetError() returns this if there is no result from the expression. private: //------------------------------------------------------------------ - /// Populate m_cplusplus and m_objetivec based on the environment. + /// Populate m_cplusplus and m_objectivec based on the environment. //------------------------------------------------------------------ void @@ -344,11 +345,11 @@ private: std::string m_transformed_text; ///< The text of the expression, as send to the parser ResultType m_desired_type; ///< The type to coerce the expression's result to. If eResultTypeAny, inferred from the expression. - std::unique_ptr m_expr_decl_map; ///< The map to use when parsing the expression. - std::unique_ptr m_execution_unit_ap; ///< The execution unit the expression is stored in. - std::unique_ptr m_materializer_ap; ///< The materializer to use when running the expression. - std::unique_ptr m_result_synthesizer; ///< The result synthesizer, if one is needed. - + std::unique_ptr m_expr_decl_map; ///< The map to use when parsing the expression. + std::shared_ptr m_execution_unit_sp; ///< The execution unit the expression is stored in. + std::unique_ptr m_materializer_ap; ///< The materializer to use when running the expression. + std::unique_ptr m_result_synthesizer; ///< The result synthesizer, if one is needed. + lldb::ModuleWP m_jit_module_wp; bool m_enforce_valid_object; ///< True if the expression parser should enforce the presence of a valid class pointer in order to generate the expression as a method. bool m_cplusplus; ///< True if the expression is compiled as a C++ member function (true if it was parsed when exe_ctx was in a C++ method). bool m_objectivec; ///< True if the expression is compiled as an Objective-C method (true if it was parsed when exe_ctx was in an Objective-C method). diff --git a/include/lldb/Expression/ClangUtilityFunction.h b/include/lldb/Expression/ClangUtilityFunction.h index 6da8e5ec3a8b..bb5601fa2914 100644 --- a/include/lldb/Expression/ClangUtilityFunction.h +++ b/include/lldb/Expression/ClangUtilityFunction.h @@ -168,10 +168,10 @@ public: private: std::unique_ptr m_expr_decl_map; ///< The map to use when parsing and materializing the expression. - std::unique_ptr m_execution_unit_ap; - - std::string m_function_text; ///< The text of the function. Must be a well-formed translation unit. - std::string m_function_name; ///< The name of the function. + std::shared_ptr m_execution_unit_sp; + lldb::ModuleWP m_jit_module_wp; + std::string m_function_text; ///< The text of the function. Must be a well-formed translation unit. + std::string m_function_name; ///< The name of the function. }; } // namespace lldb_private diff --git a/include/lldb/Expression/DWARFExpression.h b/include/lldb/Expression/DWARFExpression.h index 5ecdf7fe9ee5..9ddecc053e00 100644 --- a/include/lldb/Expression/DWARFExpression.h +++ b/include/lldb/Expression/DWARFExpression.h @@ -222,6 +222,17 @@ public: lldb::offset_t data_offset, lldb::offset_t data_length); + void + CopyOpcodeData (const void *data, + lldb::offset_t data_length, + lldb::ByteOrder byte_order, + uint8_t addr_byte_size); + + void + CopyOpcodeData (uint64_t const_value, + lldb::offset_t const_value_byte_size, + uint8_t addr_byte_size); + //------------------------------------------------------------------ /// Tells the expression that it refers to a location list. @@ -347,7 +358,7 @@ public: const DataExtractor& opcodes, const lldb::offset_t offset, const lldb::offset_t length, - const uint32_t reg_set, + const lldb::RegisterKind reg_set, const Value* initial_value_ptr, Value& result, Error *error_ptr); diff --git a/include/lldb/Expression/ExpressionSourceCode.h b/include/lldb/Expression/ExpressionSourceCode.h index be1014ae3047..2dd09378fcd2 100644 --- a/include/lldb/Expression/ExpressionSourceCode.h +++ b/include/lldb/Expression/ExpressionSourceCode.h @@ -17,6 +17,8 @@ namespace lldb_private { +class ExecutionContext; + class ExpressionSourceCode { public: @@ -53,7 +55,8 @@ public: bool GetText (std::string &text, lldb::LanguageType wrapping_language, bool const_object, - bool static_method) const; + bool static_method, + ExecutionContext &exe_ctx) const; private: ExpressionSourceCode (const char *name, diff --git a/include/lldb/Expression/IRExecutionUnit.h b/include/lldb/Expression/IRExecutionUnit.h index 2820317e108e..3f28351a6928 100644 --- a/include/lldb/Expression/IRExecutionUnit.h +++ b/include/lldb/Expression/IRExecutionUnit.h @@ -30,6 +30,7 @@ #include "lldb/Expression/ClangExpressionParser.h" #include "lldb/Expression/IRMemoryMap.h" #include "lldb/Host/Mutex.h" +#include "lldb/Symbol/ObjectFile.h" namespace llvm { @@ -60,7 +61,10 @@ class Error; /// into the target process, the IRExecutionUnit knows how to copy the /// emitted code into the target process. //---------------------------------------------------------------------- -class IRExecutionUnit : public IRMemoryMap +class IRExecutionUnit : + public std::enable_shared_from_this, + public IRMemoryMap, + public ObjectFileJITDelegate { public: //------------------------------------------------------------------ @@ -77,12 +81,14 @@ public: //------------------------------------------------------------------ ~IRExecutionUnit(); - llvm::Module *GetModule() + llvm::Module * + GetModule() { return m_module; } - llvm::Function *GetFunction() + llvm::Function * + GetFunction() { if (m_module) return m_module->getFunction (m_name.AsCString()); @@ -90,9 +96,10 @@ public: return NULL; } - void GetRunnableInfo(Error &error, - lldb::addr_t &func_addr, - lldb::addr_t &func_end); + void + GetRunnableInfo (Error &error, + lldb::addr_t &func_addr, + lldb::addr_t &func_end); //------------------------------------------------------------------ /// Accessors for IRForTarget and other clients that may want binary @@ -100,11 +107,36 @@ public: /// IRExecutionUnit unless the client explicitly chooses to free it. //------------------------------------------------------------------ - lldb::addr_t WriteNow(const uint8_t *bytes, - size_t size, - Error &error); + lldb::addr_t + WriteNow (const uint8_t *bytes, + size_t size, + Error &error); + + void + FreeNow (lldb::addr_t allocation); + + //------------------------------------------------------------------ + /// ObjectFileJITDelegate overrides + //------------------------------------------------------------------ + virtual lldb::ByteOrder + GetByteOrder () const; - void FreeNow(lldb::addr_t allocation); + virtual uint32_t + GetAddressByteSize () const; + + virtual void + PopulateSymtab (lldb_private::ObjectFile *obj_file, + lldb_private::Symtab &symtab); + + virtual void + PopulateSectionList (lldb_private::ObjectFile *obj_file, + lldb_private::SectionList §ion_list); + + virtual bool + GetArchitecture (lldb_private::ArchSpec &arch); + + lldb::ModuleSP + GetJITModule (); private: //------------------------------------------------------------------ @@ -180,6 +212,7 @@ private: public: MemoryManager (IRExecutionUnit &parent); + virtual ~MemoryManager(); //------------------------------------------------------------------ /// Passthrough interface stub //------------------------------------------------------------------ @@ -423,7 +456,7 @@ private: //------------------------------------------------------------------ /// Constructor /// - /// Initializes class variabes. + /// Initializes class variables. /// /// @param[in] name /// The name of the function. @@ -450,31 +483,47 @@ private: //---------------------------------------------------------------------- /// @class AllocationRecord IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h" - /// @brief Enacpsulates a single allocation request made by the JIT. + /// @brief Encapsulates a single allocation request made by the JIT. /// /// Allocations made by the JIT are first queued up and then applied in /// bulk to the underlying process. //---------------------------------------------------------------------- + enum class AllocationKind { + Stub, Code, Data, Global, Bytes + }; + + static lldb::SectionType + GetSectionTypeFromSectionName (const llvm::StringRef &name, + AllocationKind alloc_kind); + struct AllocationRecord { - lldb::addr_t m_process_address; - uintptr_t m_host_address; - uint32_t m_permissions; - size_t m_size; - unsigned m_alignment; - unsigned m_section_id; + std::string m_name; + lldb::addr_t m_process_address; + uintptr_t m_host_address; + uint32_t m_permissions; + lldb::SectionType m_sect_type; + size_t m_size; + unsigned m_alignment; + unsigned m_section_id; AllocationRecord (uintptr_t host_address, uint32_t permissions, + lldb::SectionType sect_type, size_t size, unsigned alignment, - unsigned section_id = eSectionIDInvalid) : + unsigned section_id, + const char *name) : + m_name (), m_process_address(LLDB_INVALID_ADDRESS), m_host_address(host_address), m_permissions(permissions), + m_sect_type (sect_type), m_size(size), m_alignment(alignment), m_section_id(section_id) { + if (name && name[0]) + m_name = name; } void dump (Log *log); diff --git a/include/lldb/Expression/IRForTarget.h b/include/lldb/Expression/IRForTarget.h index 502f796d15a1..0ad34904f563 100644 --- a/include/lldb/Expression/IRForTarget.h +++ b/include/lldb/Expression/IRForTarget.h @@ -61,6 +61,12 @@ namespace lldb_private { class IRForTarget : public llvm::ModulePass { public: + enum class LookupResult { + Success, + Fail, + Ignore + }; + //------------------------------------------------------------------ /// Constructor /// @@ -182,7 +188,7 @@ private: //------------------------------------------------------------------ //------------------------------------------------------------------ - /// Get the address of a fuction, and a location to put the complete + /// Get the address of a function, and a location to put the complete /// Value of the function if one is available. /// /// @param[in] function @@ -201,7 +207,7 @@ private: /// @return /// The pointer. //------------------------------------------------------------------ - bool + LookupResult GetFunctionAddress (llvm::Function *function, uint64_t &ptr, lldb_private::ConstString &name, @@ -573,7 +579,7 @@ private: ReplaceStrings (); //------------------------------------------------------------------ - /// A basick block-level pass to find all literals that will be + /// A basic block-level pass to find all literals that will be /// allocated as statics by the JIT (in contrast to the Strings, /// which already are statics) and synthesize loads for them. //------------------------------------------------------------------ diff --git a/include/lldb/Expression/IRMemoryMap.h b/include/lldb/Expression/IRMemoryMap.h index affe19350e3f..4faa5226d9b4 100644 --- a/include/lldb/Expression/IRMemoryMap.h +++ b/include/lldb/Expression/IRMemoryMap.h @@ -27,7 +27,8 @@ namespace lldb_private /// This class encapsulates a group of memory objects that must be readable /// or writable from the host process regardless of whether the process /// exists. This allows the IR interpreter as well as JITted code to access -/// the same memory. +/// the same memory. All allocations made by this class are represented as +/// disjoint intervals. /// /// Point queries against this group of memory objects can be made by the /// address in the tar at which they reside. If the inferior does not @@ -66,7 +67,7 @@ public: uint32_t GetAddressByteSize(); // This function can return NULL. - ExecutionContextScope *GetBestExecutionContextScope(); + ExecutionContextScope *GetBestExecutionContextScope() const; protected: // This function should only be used if you know you are using the JIT. @@ -118,7 +119,12 @@ private: lldb::addr_t FindSpace (size_t size); bool ContainsHostOnlyAllocations (); AllocationMap::iterator FindAllocation (lldb::addr_t addr, size_t size); - bool IntersectsAllocation (lldb::addr_t addr, size_t size); + + // Returns true if the given allocation intersects any allocation in the memory map. + bool IntersectsAllocation (lldb::addr_t addr, size_t size) const; + + // Returns true if the two given allocations intersect each other. + static bool AllocationsIntersect (lldb::addr_t addr1, size_t size1, lldb::addr_t addr2, size_t size2); }; } diff --git a/include/lldb/Host/Condition.h b/include/lldb/Host/Condition.h index 2f1858b75a56..7431315c37a0 100644 --- a/include/lldb/Host/Condition.h +++ b/include/lldb/Host/Condition.h @@ -25,7 +25,7 @@ class TimeValue; /// /// A class that wraps up a pthread condition (pthread_cond_t). The /// class will create a pthread condition when an instance is -/// constructed, and detroy it when it is destructed. It also provides +/// constructed, and destroy it when it is destructed. It also provides /// access to the standard pthread condition calls. //---------------------------------------------------------------------- class Condition diff --git a/include/lldb/Host/Config.h b/include/lldb/Host/Config.h index 80616b747cf5..af6b98a7912a 100644 --- a/include/lldb/Host/Config.h +++ b/include/lldb/Host/Config.h @@ -18,7 +18,7 @@ #include "lldb/Host/linux/Config.h" -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__NetBSD__) #include "lldb/Host/freebsd/Config.h" diff --git a/include/lldb/Host/Debug.h b/include/lldb/Host/Debug.h index 2cb758e1b733..87dffb9865c2 100644 --- a/include/lldb/Host/Debug.h +++ b/include/lldb/Host/Debug.h @@ -10,14 +10,11 @@ #ifndef liblldb_Debug_h_ #define liblldb_Debug_h_ -#include "lldb/lldb-private.h" -#include "lldb/Core/Error.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Host/Mutex.h" #include +#include "lldb/lldb-private.h" namespace lldb_private { - + //------------------------------------------------------------------ // Tells a thread what it needs to do when the process is resumed. //------------------------------------------------------------------ @@ -27,7 +24,7 @@ namespace lldb_private { lldb::StateType state; // Valid values are eStateStopped/eStateSuspended, eStateRunning, and eStateStepping. int signal; // When resuming this thread, resume it with this signal if this value is > 0 }; - + //------------------------------------------------------------------ // A class that contains instructions for all threads for // NativeProcessProtocol::Resume(). Each thread can either run, stay @@ -43,15 +40,14 @@ namespace lldb_private { m_signal_handled () { } - + ResumeActionList (lldb::StateType default_action, int signal) : m_actions(), m_signal_handled () { SetDefaultThreadActionIfNeeded (default_action, signal); } - - + ResumeActionList (const ResumeAction *actions, size_t num_actions) : m_actions (), m_signal_handled () @@ -62,7 +58,7 @@ namespace lldb_private { m_signal_handled.assign (num_actions, false); } } - + ~ResumeActionList() { } @@ -72,14 +68,14 @@ namespace lldb_private { { return m_actions.empty(); } - + void Append (const ResumeAction &action) { m_actions.push_back (action); m_signal_handled.push_back (false); } - + void AppendAction (lldb::tid_t tid, lldb::StateType state, @@ -88,25 +84,25 @@ namespace lldb_private { ResumeAction action = { tid, state, signal }; Append (action); } - + void AppendResumeAll () { AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateRunning); } - + void AppendSuspendAll () { AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateStopped); } - + void AppendStepAll () { AppendAction (LLDB_INVALID_THREAD_ID, lldb::eStateStepping); } - + const ResumeAction * GetActionForThread (lldb::tid_t tid, bool default_ok) const { @@ -120,7 +116,7 @@ namespace lldb_private { return GetActionForThread (LLDB_INVALID_THREAD_ID, false); return NULL; } - + size_t NumActionsWithState (lldb::StateType state) const { @@ -133,7 +129,7 @@ namespace lldb_private { } return count; } - + bool SetDefaultThreadActionIfNeeded (lldb::StateType action, int signal) { @@ -147,7 +143,7 @@ namespace lldb_private { } return false; } - + void SetSignalHandledForThread (lldb::tid_t tid) const { @@ -161,26 +157,26 @@ namespace lldb_private { } } } - + const ResumeAction * GetFirst() const { return m_actions.data(); } - + size_t GetSize () const { return m_actions.size(); } - + void Clear() { m_actions.clear(); m_signal_handled.clear(); } - + protected: std::vector m_actions; mutable std::vector m_signal_handled; @@ -191,13 +187,13 @@ namespace lldb_private { lldb::StopReason reason; union { - // eStopTypeSignal + // eStopReasonSignal struct { uint32_t signo; } signal; - - // eStopTypeException + + // eStopReasonException struct { uint64_t type; @@ -206,201 +202,5 @@ namespace lldb_private { } exception; } details; }; - - //------------------------------------------------------------------ - // NativeThreadProtocol - //------------------------------------------------------------------ - class NativeThreadProtocol { - - public: - NativeThreadProtocol (NativeProcessProtocol *process, lldb::tid_t tid) : - m_process (process), - m_tid (tid) - { - } - - virtual ~NativeThreadProtocol() - { - } - virtual const char *GetName() = 0; - virtual lldb::StateType GetState () = 0; - virtual Error ReadRegister (uint32_t reg, RegisterValue ®_value) = 0; - virtual Error WriteRegister (uint32_t reg, const RegisterValue ®_value) = 0; - virtual Error SaveAllRegisters (lldb::DataBufferSP &data_sp) = 0; - virtual Error RestoreAllRegisters (lldb::DataBufferSP &data_sp) = 0; - virtual bool GetStopReason (ThreadStopInfo &stop_info) = 0; - - lldb::tid_t - GetID() const - { - return m_tid; - } - protected: - NativeProcessProtocol *m_process; - lldb::tid_t m_tid; - }; - - - //------------------------------------------------------------------ - // NativeProcessProtocol - //------------------------------------------------------------------ - class NativeProcessProtocol { - public: - - static NativeProcessProtocol * - CreateInstance (lldb::pid_t pid); - - // lldb_private::Host calls should be used to launch a process for debugging, and - // then the process should be attached to. When attaching to a process - // lldb_private::Host calls should be used to locate the process to attach to, - // and then this function should be called. - NativeProcessProtocol (lldb::pid_t pid) : - m_pid (pid), - m_threads(), - m_threads_mutex (Mutex::eMutexTypeRecursive), - m_state (lldb::eStateInvalid), - m_exit_status(0), - m_exit_description() - { - } - - public: - virtual ~NativeProcessProtocol () - { - } - - virtual Error Resume (const ResumeActionList &resume_actions) = 0; - virtual Error Halt () = 0; - virtual Error Detach () = 0; - virtual Error Signal (int signo) = 0; - virtual Error Kill () = 0; - - virtual Error ReadMemory (lldb::addr_t addr, void *buf, lldb::addr_t size, lldb::addr_t &bytes_read) = 0; - virtual Error WriteMemory (lldb::addr_t addr, const void *buf, lldb::addr_t size, lldb::addr_t &bytes_written) = 0; - virtual Error AllocateMemory (lldb::addr_t size, uint32_t permissions, lldb::addr_t &addr) = 0; - virtual Error DeallocateMemory (lldb::addr_t addr) = 0; - - virtual lldb::addr_t GetSharedLibraryInfoAddress () = 0; - - virtual bool IsAlive () = 0; - virtual size_t UpdateThreads () = 0; - virtual bool GetArchitecture (ArchSpec &arch) = 0; - - //---------------------------------------------------------------------- - // Breakpoint functions - //---------------------------------------------------------------------- - virtual Error SetBreakpoint (lldb::addr_t addr, size_t size, bool hardware) = 0; - virtual Error RemoveBreakpoint (lldb::addr_t addr, size_t size) = 0; - - //---------------------------------------------------------------------- - // Watchpoint functions - //---------------------------------------------------------------------- - virtual uint32_t GetMaxWatchpoints () = 0; - virtual Error SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) = 0; - virtual Error RemoveWatchpoint (lldb::addr_t addr) = 0; - - - //---------------------------------------------------------------------- - // Accessors - //---------------------------------------------------------------------- - lldb::pid_t - GetID() const - { - return m_pid; - } - - lldb::StateType - GetState () const - { - return m_state; - } - - bool - IsRunning () const - { - return m_state == lldb::eStateRunning || IsStepping(); - } - - bool - IsStepping () const - { - return m_state == lldb::eStateStepping; - } - - bool - CanResume () const - { - return m_state == lldb::eStateStopped; - } - - - void - SetState (lldb::StateType state) - { - m_state = state; - } - - //---------------------------------------------------------------------- - // Exit Status - //---------------------------------------------------------------------- - virtual bool - GetExitStatus (int *status) - { - if (m_state == lldb::eStateExited) - { - *status = m_exit_status; - return true; - } - *status = 0; - return false; - } - virtual bool - SetExitStatus (int status, const char *exit_description) - { - // Exit status already set - if (m_state == lldb::eStateExited) - return false; - m_state = lldb::eStateExited; - m_exit_status = status; - if (exit_description && exit_description[0]) - m_exit_description = exit_description; - else - m_exit_description.clear(); - return true; - } - - //---------------------------------------------------------------------- - // Access to threads - //---------------------------------------------------------------------- - lldb::NativeThreadProtocolSP - GetThreadAtIndex (uint32_t idx) - { - Mutex::Locker locker(m_threads_mutex); - if (idx < m_threads.size()) - return m_threads[idx]; - return lldb::NativeThreadProtocolSP(); - } - - lldb::NativeThreadProtocolSP - GetThreadByID (lldb::tid_t tid) - { - Mutex::Locker locker(m_threads_mutex); - for (auto thread_sp : m_threads) - { - if (thread_sp->GetID() == tid) - return thread_sp; - } - return lldb::NativeThreadProtocolSP(); - } - - protected: - lldb::pid_t m_pid; - std::vector m_threads; - mutable Mutex m_threads_mutex; - lldb::StateType m_state; - int m_exit_status; - std::string m_exit_description; - }; - } #endif // #ifndef liblldb_Debug_h_ diff --git a/include/lldb/Host/DynamicLibrary.h b/include/lldb/Host/DynamicLibrary.h deleted file mode 100644 index 1fcc7d1883cf..000000000000 --- a/include/lldb/Host/DynamicLibrary.h +++ /dev/null @@ -1,51 +0,0 @@ -//===-- DynamicLibrary.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_DynamicLibrary_h_ -#define liblldb_DynamicLibrary_h_ - -#include "lldb/Host/FileSpec.h" -#include "lldb/Host/Host.h" - -namespace lldb_private { - -class DynamicLibrary -{ -public: - DynamicLibrary (const FileSpec& spec, uint32_t options = Host::eDynamicLibraryOpenOptionLazy | - Host::eDynamicLibraryOpenOptionLocal | - Host::eDynamicLibraryOpenOptionLimitGetSymbol); - - ~DynamicLibrary (); - - template - T GetSymbol (const char* name) - { - Error err; - if (!m_handle) - return (T)NULL; - void* symbol = Host::DynamicLibraryGetSymbol (m_handle, name, err); - if (!symbol) - return (T)NULL; - return (T)symbol; - } - - bool - IsValid (); - -private: - lldb_private::FileSpec m_filespec; - void* m_handle; - - DISALLOW_COPY_AND_ASSIGN (DynamicLibrary); -}; - -} // namespace lldb_private - -#endif // liblldb_DynamicLibrary_h_ diff --git a/include/lldb/Host/Editline.h b/include/lldb/Host/Editline.h index b92de1052f29..5cba8465d654 100644 --- a/include/lldb/Host/Editline.h +++ b/include/lldb/Host/Editline.h @@ -23,9 +23,11 @@ #include #include +#include "lldb/Core/ConnectionFileDescriptor.h" #include "lldb/Host/Condition.h" #include "lldb/Host/FileSpec.h" #include "lldb/Host/Mutex.h" +#include "lldb/Host/Predicate.h" namespace lldb_private { @@ -33,6 +35,10 @@ namespace lldb_private { /// @class Editline Editline.h "lldb/Host/Editline.h" /// @brief A class that encapsulates editline functionality. //---------------------------------------------------------------------- +class EditlineHistory; + +typedef std::shared_ptr EditlineHistorySP; + class Editline { public: @@ -58,6 +64,7 @@ public: Editline(const char *prog, // Used for the history file and for editrc program name const char *prompt, + bool configure_for_multiline, FILE *fin, FILE *fout, FILE *ferr); @@ -65,10 +72,13 @@ public: ~Editline(); Error - GetLine (std::string &line); + GetLine (std::string &line, + bool &interrupted); Error - GetLines (const std::string &end_line, StringList &lines); + GetLines (const std::string &end_line, + StringList &lines, + bool &interrupted); bool LoadHistory (); @@ -97,7 +107,7 @@ public: void Refresh(); - void + bool Interrupt (); void @@ -118,11 +128,6 @@ public: size_t Push (const char *bytes, size_t len); - - // Cache bytes and use them for input without using a FILE. Calling this function - // will set the getc callback in the editline - size_t - SetInputBuffer (const char *c, size_t len); static int GetCharFromInputFileCallback (::EditLine *e, char *c); @@ -135,21 +140,21 @@ public: void SetPrompt (const char *p); - + + void + ShowLineNumbers (bool enable, uint32_t line_offset) + { + m_prompt_with_line_numbers = enable; + m_line_offset = line_offset; + } + private: Error PrivateGetLine(std::string &line); - FileSpec - GetHistoryFile(); - unsigned char HandleCompletion (int ch); - - int - GetChar (char *c); - static unsigned char CallbackEditPrevLine (::EditLine *e, int ch); @@ -169,9 +174,6 @@ private: static FILE * GetFilePointer (::EditLine *e, int fd); - static int - GetCharInputBufferCallback (::EditLine *e, char *c); - enum class Command { None = 0, @@ -179,22 +181,19 @@ private: EditNextLine, }; ::EditLine *m_editline; - ::History *m_history; - ::HistEvent m_history_event; - std::string m_program; + EditlineHistorySP m_history_sp; std::string m_prompt; std::string m_lines_prompt; - std::string m_getc_buffer; - Mutex m_getc_mutex; - Condition m_getc_cond; + lldb_private::Predicate m_getting_char; CompleteCallbackType m_completion_callback; void *m_completion_callback_baton; -// Mutex m_gets_mutex; // Make sure only one thread LineCompletedCallbackType m_line_complete_callback; void *m_line_complete_callback_baton; Command m_lines_command; + uint32_t m_line_offset; uint32_t m_lines_curr_line; uint32_t m_lines_max_line; + ConnectionFileDescriptor m_file; bool m_prompt_with_line_numbers; bool m_getting_line; bool m_got_eof; // Set to true when we detect EOF diff --git a/include/lldb/Host/Endian.h b/include/lldb/Host/Endian.h index 610f3ce95c41..1ae3c40b5ca4 100644 --- a/include/lldb/Host/Endian.h +++ b/include/lldb/Host/Endian.h @@ -20,7 +20,7 @@ namespace endian { { uint32_t num; uint8_t bytes[sizeof(uint32_t)]; - } const endianTest = { (uint16_t)0x01020304 }; + } const endianTest = { 0x01020304 }; inline ByteOrder InlHostByteOrder() { return (ByteOrder)endianTest.bytes[0]; } diff --git a/include/lldb/Host/File.h b/include/lldb/Host/File.h index 814d96059f37..2738679b5e03 100644 --- a/include/lldb/Host/File.h +++ b/include/lldb/Host/File.h @@ -16,6 +16,7 @@ #include #include "lldb/lldb-private.h" +#include "lldb/Host/IOObject.h" namespace lldb_private { @@ -26,7 +27,7 @@ namespace lldb_private { /// A file class that divides abstracts the LLDB core from host file /// functionality. //---------------------------------------------------------------------- -class File +class File : public IOObject { public: static int kInvalidDescriptor; @@ -48,22 +49,22 @@ public: ConvertOpenOptionsForPOSIXOpen (uint32_t open_options); File() : + IOObject(eFDTypeFile, false), m_descriptor (kInvalidDescriptor), m_stream (kInvalidStream), m_options (0), m_own_stream (false), - m_own_descriptor (false), m_is_interactive (eLazyBoolCalculate), m_is_real_terminal (eLazyBoolCalculate) { } File (FILE *fh, bool transfer_ownership) : + IOObject(eFDTypeFile, false), m_descriptor (kInvalidDescriptor), m_stream (fh), m_options (0), m_own_stream (transfer_ownership), - m_own_descriptor (false), m_is_interactive (eLazyBoolCalculate), m_is_real_terminal (eLazyBoolCalculate) { @@ -118,11 +119,11 @@ public: uint32_t permissions = lldb::eFilePermissionsFileDefault); File (int fd, bool transfer_ownership) : + IOObject(eFDTypeFile, transfer_ownership), m_descriptor (fd), m_stream (kInvalidStream), m_options (0), - m_own_stream (false), - m_own_descriptor (transfer_ownership) + m_own_stream (false) { } @@ -222,6 +223,10 @@ public: int GetDescriptor() const; + WaitableHandle + GetWaitableHandle(); + + void SetDescriptor(int fd, bool transfer_ownership); @@ -331,7 +336,7 @@ public: /// /// @param[in/out] offset /// The offset to seek to within the file relative to the - /// end of the file which gets filled in the the resulting + /// end of the file which gets filled in with the resulting /// absolute file offset. /// /// @param[in] error_ptr @@ -482,7 +487,7 @@ public: /// /// Just knowing a file is a interactive isn't enough, we also need /// to know if the terminal has a width and height so we can do - /// cursor movement and other terminal maninpulations by sending + /// cursor movement and other terminal manipulations by sending /// escape sequences. /// /// @return @@ -541,7 +546,6 @@ protected: FILE *m_stream; uint32_t m_options; bool m_own_stream; - bool m_own_descriptor; LazyBool m_is_interactive; LazyBool m_is_real_terminal; }; diff --git a/include/lldb/Host/FileCache.h b/include/lldb/Host/FileCache.h new file mode 100644 index 000000000000..779ff983de98 --- /dev/null +++ b/include/lldb/Host/FileCache.h @@ -0,0 +1,45 @@ +//===-- FileCache.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_Host_FileCache_h +#define liblldb_Host_FileCache_h + +#include + +#include "lldb/lldb-forward.h" +#include "lldb/lldb-types.h" + +#include "lldb/Core/Error.h" +#include "lldb/Host/FileSpec.h" + +namespace lldb_private +{ +class FileCache +{ + private: + FileCache() {} + + typedef std::map FDToFileMap; + + public: + static FileCache &GetInstance(); + + lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags, uint32_t mode, Error &error); + bool CloseFile(lldb::user_id_t fd, Error &error); + + uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, uint64_t src_len, Error &error); + uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, uint64_t dst_len, Error &error); + + private: + static FileCache *m_instance; + + FDToFileMap m_cache; +}; +} + +#endif diff --git a/include/lldb/Host/FileSpec.h b/include/lldb/Host/FileSpec.h index dfc4e4ae0fe3..ef73bb2ede0f 100644 --- a/include/lldb/Host/FileSpec.h +++ b/include/lldb/Host/FileSpec.h @@ -51,6 +51,13 @@ public: eFileTypeOther } FileType; + enum PathSyntax + { + ePathSyntaxPosix, + ePathSyntaxWindows, + ePathSyntaxHostNative + }; + FileSpec(); //------------------------------------------------------------------ @@ -69,7 +76,7 @@ public: /// /// @see FileSpec::SetFile (const char *path, bool resolve) //------------------------------------------------------------------ - explicit FileSpec (const char *path, bool resolve_path); + explicit FileSpec (const char *path, bool resolve_path, PathSyntax syntax = ePathSyntaxHostNative); //------------------------------------------------------------------ /// Copy constructor @@ -249,7 +256,7 @@ public: /// by a directory delimiter, and the filename. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. //------------------------------------------------------------------ void Dump (Stream *s) const; @@ -263,6 +270,15 @@ public: bool Exists () const; + //------------------------------------------------------------------ + /// Check if a file is readable by the current user + /// + /// @return + /// \b true if the file exists on disk and is readable, \b false + /// otherwise. + //------------------------------------------------------------------ + bool + Readable () const; //------------------------------------------------------------------ /// Expanded existence test. @@ -291,6 +307,9 @@ public: uint64_t GetByteSize() const; + PathSyntax + GetPathSyntax() const; + //------------------------------------------------------------------ /// Directory string get accessor. /// @@ -375,7 +394,7 @@ public: /// still NULL terminated). //------------------------------------------------------------------ size_t - GetPath (char *path, size_t max_path_length) const; + GetPath (char *path, size_t max_path_length, bool denormalize = true) const; //------------------------------------------------------------------ /// Extract the full path to the file. @@ -387,7 +406,7 @@ public: /// concatenated. //------------------------------------------------------------------ std::string - GetPath () const; + GetPath (bool denormalize = true) const; //------------------------------------------------------------------ /// Extract the extension of the file. @@ -486,7 +505,7 @@ public: /// Returns a shared pointer to a data buffer that contains all or /// part of the contents of a file. The data is memory mapped and /// will lazily page in data from the file as memory is accessed. - /// The data that is mappped will start \a offset bytes into the + /// The data that is mapped will start \a offset bytes into the /// file, and \a length bytes will be mapped. If \a length is /// greater than the number of bytes available in the file starting /// at \a offset, the number of bytes will be appropriately @@ -504,7 +523,7 @@ public: /// as many bytes as possible. /// /// @return - /// A shared pointer to the memeory mapped data. This shared + /// A shared pointer to the memory mapped data. This shared /// pointer can contain a NULL DataBuffer pointer, so the contained /// pointer must be checked prior to using it. //------------------------------------------------------------------ @@ -559,8 +578,12 @@ public: //------------------------------------------------------------------ lldb::DataBufferSP ReadFileContentsAsCString(Error *error_ptr = NULL); + + static void Normalize(llvm::SmallVectorImpl &path, PathSyntax syntax = ePathSyntaxHostNative); + static void DeNormalize(llvm::SmallVectorImpl &path, PathSyntax syntax = ePathSyntaxHostNative); + //------------------------------------------------------------------ - /// Change the file specificed with a new path. + /// Change the file specified with a new path. /// /// Update the contents of this object with a new path. The path will /// be split up into a directory and filename and stored as uniqued @@ -574,7 +597,7 @@ public: /// the static FileSpec::Resolve. //------------------------------------------------------------------ void - SetFile (const char *path, bool resolve_path); + SetFile (const char *path, bool resolve_path, PathSyntax syntax = ePathSyntaxHostNative); bool IsResolved () const @@ -617,27 +640,14 @@ public: ReadFileLines (STLStringArray &lines); //------------------------------------------------------------------ - /// Resolves user name and links in \a src_path, and writes the output - /// to \a dst_path. Note if the path pointed to by \a src_path does not - /// exist, the contents of \a src_path will be copied to \a dst_path - /// unchanged. + /// Resolves user name and links in \a path, and overwrites the input + /// argument with the resolved path. /// - /// @param[in] src_path - /// Input path to be resolved. - /// - /// @param[in] dst_path - /// Buffer to store the resolved path. - /// - /// @param[in] dst_len - /// Size of the buffer pointed to by dst_path. - /// - /// @result - /// The number of characters required to write the resolved path. If the - /// resolved path doesn't fit in dst_len, dst_len-1 characters will - /// be written to \a dst_path, but the actual required length will still be returned. + /// @param[in] path + /// Input path to be resolved, in the form of a llvm::SmallString or similar. //------------------------------------------------------------------ - static size_t - Resolve (const char *src_path, char *dst_path, size_t dst_len); + static void + Resolve (llvm::SmallVectorImpl &path); FileSpec CopyByAppendingPathComponent (const char *new_path) const; @@ -665,18 +675,9 @@ public: /// /// @param[in] dst_path /// Buffer to store the resolved path. - /// - /// @param[in] dst_len - /// Size of the buffer pointed to by dst_path. - /// - /// @result - /// The number of characters required to write the resolved path, or 0 if - /// the user name could not be found. If the - /// resolved path doesn't fit in dst_len, dst_len-1 characters will - /// be written to \a dst_path, but the actual required length will still be returned. //------------------------------------------------------------------ - static size_t - ResolveUsername (const char *src_path, char *dst_path, size_t dst_len); + static void + ResolveUsername (llvm::SmallVectorImpl &path); static size_t ResolvePartialUsername (const char *partial_name, StringList &matches); @@ -709,6 +710,7 @@ protected: ConstString m_directory; ///< The uniqued directory path ConstString m_filename; ///< The uniqued filename path mutable bool m_is_resolved; ///< True if this path has been resolved. + PathSyntax m_syntax; ///< The syntax that this path uses (e.g. Windows / Posix) }; //---------------------------------------------------------------------- diff --git a/include/lldb/Host/FileSystem.h b/include/lldb/Host/FileSystem.h new file mode 100644 index 000000000000..adcbfc9d590d --- /dev/null +++ b/include/lldb/Host/FileSystem.h @@ -0,0 +1,43 @@ +//===-- FileSystem.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_Host_FileSystem_h +#define liblldb_Host_FileSystem_h + +#include + +#include "lldb/lldb-types.h" + +#include "lldb/Core/Error.h" +#include "lldb/Host/FileSpec.h" + +namespace lldb_private +{ +class FileSystem +{ + public: + static FileSpec::PathSyntax GetNativePathSyntax(); + + static Error MakeDirectory(const char *path, uint32_t mode); + static Error DeleteDirectory(const char *path, bool recurse); + + static Error GetFilePermissions(const char *path, uint32_t &file_permissions); + static Error SetFilePermissions(const char *path, uint32_t file_permissions); + static lldb::user_id_t GetFileSize(const FileSpec &file_spec); + static bool GetFileExists(const FileSpec &file_spec); + + static Error Symlink(const char *src, const char *dst); + static Error Readlink(const char *path, char *buf, size_t buf_len); + static Error Unlink(const char *path); + + static bool CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &high); +}; +} + +#endif diff --git a/include/lldb/Host/Host.h b/include/lldb/Host/Host.h index 862b1ed79432..19ed7b01e80f 100644 --- a/include/lldb/Host/Host.h +++ b/include/lldb/Host/Host.h @@ -17,11 +17,16 @@ #include #include "lldb/lldb-private.h" +#include "lldb/lldb-private-forward.h" #include "lldb/Core/StringList.h" #include "lldb/Host/File.h" +#include "lldb/Host/FileSpec.h" namespace lldb_private { +class FileAction; +class ProcessLaunchInfo; + //---------------------------------------------------------------------- /// @class Host Host.h "lldb/Host/Host.h" /// @brief A class that provides host computer information. @@ -32,6 +37,10 @@ namespace lldb_private { class Host { public: + + /// A value of std::numeric_limits::max() is used if there is no practical limit. + static const uint32_t MAX_THREAD_NAME_LENGTH; + typedef bool (*MonitorChildProcessCallback) (void *callback_baton, lldb::pid_t pid, bool exited, @@ -48,11 +57,11 @@ public: /// thread so the callback function must be thread safe. /// /// When the callback gets called, the return value indicates if - /// minotoring should stop. If \b true is returned from \a callback + /// monitoring should stop. If \b true is returned from \a callback /// the information will be removed. If \b false is returned then /// monitoring will continue. If the child process exits, the /// monitoring will automatically stop after the callback returned - /// ragardless of the callback return value. + /// regardless of the callback return value. /// /// @param[in] callback /// A function callback to call when a child receives a signal @@ -83,68 +92,6 @@ public: lldb::pid_t pid, bool monitor_signals); - //------------------------------------------------------------------ - /// Get the host page size. - /// - /// @return - /// The size in bytes of a VM page on the host system. - //------------------------------------------------------------------ - static size_t - GetPageSize(); - - //------------------------------------------------------------------ - /// Returns the endianness of the host system. - /// - /// @return - /// Returns the endianness of the host system as a lldb::ByteOrder - /// enumeration. - //------------------------------------------------------------------ - static lldb::ByteOrder - GetByteOrder (); - - //------------------------------------------------------------------ - /// Returns the number of CPUs on this current host. - /// - /// @return - /// Number of CPUs on this current host, or zero if the number - /// of CPUs can't be determined on this host. - //------------------------------------------------------------------ - static uint32_t - GetNumberCPUS (); - - static bool - GetOSVersion (uint32_t &major, - uint32_t &minor, - uint32_t &update); - - static bool - GetOSBuildString (std::string &s); - - static bool - GetOSKernelDescription (std::string &s); - - static bool - GetHostname (std::string &s); - - static const char * - GetUserName (uint32_t uid, std::string &user_name); - - static const char * - GetGroupName (uint32_t gid, std::string &group_name); - - static uint32_t - GetUserID (); - - static uint32_t - GetGroupID (); - - static uint32_t - GetEffectiveUserID (); - - static uint32_t - GetEffectiveGroupID (); - - enum SystemLogType { eSystemLogWarning, @@ -157,67 +104,6 @@ public: static void SystemLog (SystemLogType type, const char *format, va_list args); - //------------------------------------------------------------------ - /// Gets the host architecture. - /// - /// @return - /// A const architecture object that represents the host - /// architecture. - //------------------------------------------------------------------ - enum SystemDefaultArchitecture - { - eSystemDefaultArchitecture, // The overall default architecture that applications will run on this host - eSystemDefaultArchitecture32, // If this host supports 32 bit programs, return the default 32 bit arch - eSystemDefaultArchitecture64 // If this host supports 64 bit programs, return the default 64 bit arch - }; - - static const ArchSpec & - GetArchitecture (SystemDefaultArchitecture arch_kind = eSystemDefaultArchitecture); - - //------------------------------------------------------------------ - /// Gets the host vendor string. - /// - /// @return - /// A const string object containing the host vendor name. - //------------------------------------------------------------------ - static const ConstString & - GetVendorString (); - - //------------------------------------------------------------------ - /// Gets the host Operating System (OS) string. - /// - /// @return - /// A const string object containing the host OS name. - //------------------------------------------------------------------ - static const ConstString & - GetOSString (); - - //------------------------------------------------------------------ - /// Gets the host target triple as a const string. - /// - /// @return - /// A const string object containing the host target triple. - //------------------------------------------------------------------ - static const ConstString & - GetTargetTriple (); - - //------------------------------------------------------------------ - /// Gets the name of the distribution (i.e. distributor id). - /// - /// On Linux, this will return the equivalent of lsb_release -i. - /// Android will return 'android'. Other systems may return - /// nothing. - /// - /// @return - /// A ConstString reference containing the OS distribution id. - /// The return string will be all lower case, with whitespace - /// replaced with underscores. The return string will be - /// empty (result.AsCString() will return NULL) if the distribution - /// cannot be obtained. - //------------------------------------------------------------------ - static const ConstString & - GetDistributionId (); - //------------------------------------------------------------------ /// Get the process ID for the calling process. /// @@ -259,7 +145,7 @@ public: /// /// This function call lets the current host OS do any thread /// specific initialization that it needs, including naming the - /// thread. No cleanup routine is exptected to be called + /// thread. No cleanup routine is expected to be called /// /// @param[in] name /// The current thread's name in the current process. @@ -356,16 +242,6 @@ public: static bool SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name, size_t len); - //------------------------------------------------------------------ - /// Gets the FileSpec of the current process (the process that - /// that is running the LLDB code). - /// - /// @return - /// \b A file spec with the program name. - //------------------------------------------------------------------ - static FileSpec - GetProgramFileSpec (); - //------------------------------------------------------------------ /// Given an address in the current process (the process that /// is running the LLDB code), return the name of the module that @@ -383,8 +259,6 @@ public: //------------------------------------------------------------------ static FileSpec GetModuleFileSpecForHostAddress (const void *host_addr); - - //------------------------------------------------------------------ /// If you have an executable that is in a bundle and want to get @@ -410,7 +284,7 @@ public: //------------------------------------------------------------------ /// When executable files may live within a directory, where the /// directory represents an executable bundle (like the MacOSX - /// app bundles), the locate the executable within the containing + /// app bundles), then locate the executable within the containing /// bundle. /// /// @param[in,out] file @@ -425,28 +299,6 @@ public: static bool ResolveExecutableInBundle (FileSpec &file); - //------------------------------------------------------------------ - /// Find a resource files that are related to LLDB. - /// - /// Operating systems have different ways of storing shared - /// libraries and related resources. This function abstracts the - /// access to these paths. - /// - /// @param[in] path_type - /// The type of LLDB resource path you are looking for. If the - /// enumeration ends with "Dir", then only the \a file_spec's - /// directory member gets filled in. - /// - /// @param[in] file_spec - /// A file spec that gets filled in with the appriopriate path. - /// - /// @return - /// \b true if \a resource_path was resolved, \a false otherwise. - //------------------------------------------------------------------ - static bool - GetLLDBPath (PathType path_type, - FileSpec &file_spec); - //------------------------------------------------------------------ /// Set a string that can be displayed if host application crashes. /// @@ -477,14 +329,19 @@ public: static bool GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info); -#if defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) +#if defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) || defined (__NetBSD__) static short GetPosixspawnFlags (ProcessLaunchInfo &launch_info); static Error LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid); + + static bool AddPosixSpawnFileAction(void *file_actions, const FileAction *info, Log *log, Error &error); #endif + static const lldb_private::UnixSignalsSP& + GetUnixSignals (); + static lldb::pid_t LaunchApplication (const FileSpec &app_file_spec); @@ -503,6 +360,9 @@ public: static lldb::DataBufferSP GetAuxvData (lldb_private::Process *process); + static lldb::DataBufferSP + GetAuxvData (lldb::pid_t pid); + static lldb::TargetSP GetDummyTarget (Debugger &debugger); @@ -515,79 +375,6 @@ public: static size_t GetEnvironment (StringList &env); - - enum DynamicLibraryOpenOptions - { - eDynamicLibraryOpenOptionLazy = (1u << 0), // Lazily resolve symbols in this dynamic library - eDynamicLibraryOpenOptionLocal = (1u << 1), // Only open a shared library with local access (hide it from the global symbol namespace) - eDynamicLibraryOpenOptionLimitGetSymbol = (1u << 2) // DynamicLibraryGetSymbol calls on this handle will only return matches from this shared library - }; - static void * - DynamicLibraryOpen (const FileSpec &file_spec, - uint32_t options, - Error &error); - - static Error - DynamicLibraryClose (void *dynamic_library_handle); - - static void * - DynamicLibraryGetSymbol (void *dynamic_library_handle, - const char *symbol_name, - Error &error); - - static Error - MakeDirectory (const char* path, uint32_t mode); - - static Error - GetFilePermissions (const char* path, uint32_t &file_permissions); - - static Error - SetFilePermissions (const char* path, uint32_t file_permissions); - - static Error - Symlink (const char *src, const char *dst); - - static Error - Readlink (const char *path, char *buf, size_t buf_len); - - static Error - Unlink (const char *path); - - static lldb::user_id_t - OpenFile (const FileSpec& file_spec, - uint32_t flags, - uint32_t mode, - Error &error); - - static bool - CloseFile (lldb::user_id_t fd, - Error &error); - - static uint64_t - WriteFile (lldb::user_id_t fd, - uint64_t offset, - const void* src, - uint64_t src_len, - Error &error); - - static uint64_t - ReadFile (lldb::user_id_t fd, - uint64_t offset, - void* dst, - uint64_t dst_len, - Error &error); - - static lldb::user_id_t - GetFileSize (const FileSpec& file_spec); - - static bool - GetFileExists (const FileSpec& file_spec); - - static bool - CalculateMD5 (const FileSpec& file_spec, - uint64_t &low, - uint64_t &high); - }; } // namespace lldb_private diff --git a/include/lldb/Host/HostGetOpt.h b/include/lldb/Host/HostGetOpt.h index f4b2c87be230..761c1a118600 100644 --- a/include/lldb/Host/HostGetOpt.h +++ b/include/lldb/Host/HostGetOpt.h @@ -10,11 +10,15 @@ #ifndef _MSC_VER +#ifdef _WIN32 +#define _BSD_SOURCE // Required so that getopt.h defines optreset +#endif + #include #include #else -#include +#include #endif diff --git a/include/lldb/Host/HostInfo.h b/include/lldb/Host/HostInfo.h new file mode 100644 index 000000000000..cbbf6cd2d49c --- /dev/null +++ b/include/lldb/Host/HostInfo.h @@ -0,0 +1,61 @@ +//===-- HostInfoBase.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_Host_HostInfo_h_ +#define lldb_Host_HostInfo_h_ + +//---------------------------------------------------------------------- +/// @class HostInfo HostInfo.h "lldb/Host/HostInfo.h" +/// @brief A class that provides host computer information. +/// +/// HostInfo is a class that answers information about the host operating +/// system. Note that HostInfo is NOT intended to be used to manipulate or +/// control the operating system. +/// +/// HostInfo is implemented in an OS-specific class (for example +/// HostInfoWindows) in a separate file, and then typedefed to HostInfo here. +/// Users of the class reference it as HostInfo::method(). +/// +/// Not all hosts provide the same functionality. It is important that methods +/// only be implemented at the lowest level at which they make sense. It should +/// be up to the clients of the class to ensure that they not attempt to call a +/// method which doesn't make sense for a particular platform. For example, +/// when implementing a method that only makes sense on a posix-compliant +/// system, implement it on HostInfoPosix, and not on HostInfoBase with a +/// default implementation. This way, users of HostInfo are required to think +/// about the implications of calling a particular method and if used in a +/// context where the method doesn't make sense, will generate a compiler error. +/// +//---------------------------------------------------------------------- + +#if defined(_WIN32) +#include "lldb/Host/windows/HostInfoWindows.h" +#define HOST_INFO_TYPE HostInfoWindows +#elif defined(__linux__) +#include "lldb/Host/linux/HostInfoLinux.h" +#define HOST_INFO_TYPE HostInfoLinux +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#include "lldb/Host/freebsd/HostInfoFreeBSD.h" +#define HOST_INFO_TYPE HostInfoFreeBSD +#elif defined(__APPLE__) +#include "lldb/Host/macosx/HostInfoMacOSX.h" +#define HOST_INFO_TYPE HostInfoMacOSX +#else +#include "lldb/Host/posix/HostInfoPosix.h" +#define HOST_INFO_TYPE HostInfoPosix +#endif + +namespace lldb_private +{ +typedef HOST_INFO_TYPE HostInfo; +} + +#undef HOST_INFO_TYPE + +#endif diff --git a/include/lldb/Host/HostInfoBase.h b/include/lldb/Host/HostInfoBase.h new file mode 100644 index 000000000000..f890dbc0b01b --- /dev/null +++ b/include/lldb/Host/HostInfoBase.h @@ -0,0 +1,119 @@ +//===-- HostInfoBase.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_Host_HostInfoBase_h_ +#define lldb_Host_HostInfoBase_h_ + +#include "lldb/Core/ArchSpec.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/lldb-enumerations.h" + +#include "llvm/ADT/StringRef.h" + +#include + +#include + +namespace lldb_private +{ + +class FileSpec; + +class HostInfoBase +{ + private: + // Static class, unconstructable. + HostInfoBase() {} + ~HostInfoBase() {} + + public: + static void Initialize(); + + //------------------------------------------------------------------ + /// Returns the number of CPUs on this current host. + /// + /// @return + /// Number of CPUs on this current host, or zero if the number + /// of CPUs can't be determined on this host. + //------------------------------------------------------------------ + static uint32_t GetNumberCPUS(); + + //------------------------------------------------------------------ + /// Gets the host vendor string. + /// + /// @return + /// A const string object containing the host vendor name. + //------------------------------------------------------------------ + static llvm::StringRef GetVendorString(); + + //------------------------------------------------------------------ + /// Gets the host Operating System (OS) string. + /// + /// @return + /// A const string object containing the host OS name. + //------------------------------------------------------------------ + static llvm::StringRef GetOSString(); + + //------------------------------------------------------------------ + /// Gets the host target triple as a const string. + /// + /// @return + /// A const string object containing the host target triple. + //------------------------------------------------------------------ + static llvm::StringRef GetTargetTriple(); + + //------------------------------------------------------------------ + /// Gets the host architecture. + /// + /// @return + /// A const architecture object that represents the host + /// architecture. + //------------------------------------------------------------------ + enum ArchitectureKind + { + eArchKindDefault, // The overall default architecture that applications will run on this host + eArchKind32, // If this host supports 32 bit programs, return the default 32 bit arch + eArchKind64 // If this host supports 64 bit programs, return the default 64 bit arch + }; + + static const ArchSpec &GetArchitecture(ArchitectureKind arch_kind = eArchKindDefault); + + //------------------------------------------------------------------ + /// Find a resource files that are related to LLDB. + /// + /// Operating systems have different ways of storing shared + /// libraries and related resources. This function abstracts the + /// access to these paths. + /// + /// @param[in] path_type + /// The type of LLDB resource path you are looking for. If the + /// enumeration ends with "Dir", then only the \a file_spec's + /// directory member gets filled in. + /// + /// @param[in] file_spec + /// A file spec that gets filled in with the appropriate path. + /// + /// @return + /// \b true if \a resource_path was resolved, \a false otherwise. + //------------------------------------------------------------------ + static bool GetLLDBPath(lldb::PathType type, FileSpec &file_spec); + + protected: + static bool ComputeSharedLibraryDirectory(FileSpec &file_spec); + static bool ComputeSupportExeDirectory(FileSpec &file_spec); + static bool ComputeTempFileDirectory(FileSpec &file_spec); + static bool ComputeHeaderDirectory(FileSpec &file_spec); + static bool ComputeSystemPluginsDirectory(FileSpec &file_spec); + static bool ComputeUserPluginsDirectory(FileSpec &file_spec); + + static void ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64); +}; +} + +#endif diff --git a/include/lldb/Host/HostProcess.h b/include/lldb/Host/HostProcess.h new file mode 100644 index 000000000000..2c10709ce942 --- /dev/null +++ b/include/lldb/Host/HostProcess.h @@ -0,0 +1,44 @@ +//===-- HostProcess.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_Host_HostProcess_h_ +#define lldb_Host_HostProcess_h_ + +//---------------------------------------------------------------------- +/// @class HostInfo HostInfo.h "lldb/Host/HostProcess.h" +/// @brief A class that represents a running process on the host machine. +/// +/// HostProcess allows querying and manipulation of processes running on the +/// host machine. It is not intended to be represent a process which is +/// being debugged, although the native debug engine of a platform may likely +/// back inferior processes by a HostProcess. +/// +/// HostProcess is implemented using static polymorphism so that on any given +/// platform, an instance of HostProcess will always be able to bind statically +/// to the concrete Process implementation for that platform. See HostInfo +/// for more details. +/// +//---------------------------------------------------------------------- + +#if defined(_WIN32) +#include "lldb/Host/windows/HostProcessWindows.h" +#define HOST_PROCESS_TYPE HostProcessWindows +#else +#include "lldb/Host/posix/HostProcessPosix.h" +#define HOST_PROCESS_TYPE HostProcessPosix +#endif + +namespace lldb_private +{ + typedef HOST_PROCESS_TYPE HostProcess; +} + +#undef HOST_PROCESS_TYPE + +#endif diff --git a/include/lldb/Host/IOObject.h b/include/lldb/Host/IOObject.h new file mode 100644 index 000000000000..532b1fd1bfce --- /dev/null +++ b/include/lldb/Host/IOObject.h @@ -0,0 +1,61 @@ +//===-- IOObject.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_Host_Common_IOObject_h_ +#define liblldb_Host_Common_IOObject_h_ + +#include +#include +#include + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class IOObject +{ +public: + typedef enum + { + eFDTypeFile, // Other FD requiring read/write + eFDTypeSocket, // Socket requiring send/recv + } FDType; + + // TODO: On Windows this should be a HANDLE, and wait should use + // WaitForMultipleObjects + typedef int WaitableHandle; + static const WaitableHandle kInvalidHandleValue; + + IOObject(FDType type, bool should_close) + : m_fd_type(type) + , m_should_close_fd(should_close) + { + } + virtual ~IOObject() {} + + virtual Error Read (void *buf, size_t &num_bytes) = 0; + virtual Error Write (const void *buf, size_t &num_bytes) = 0; + virtual bool IsValid() const = 0; + virtual Error Close() = 0; + + FDType GetFdType() const { return m_fd_type; } + + virtual WaitableHandle GetWaitableHandle() = 0; + +protected: + FDType m_fd_type; + bool m_should_close_fd; // True if this class should close the file descriptor when it goes away. + +private: + DISALLOW_COPY_AND_ASSIGN (IOObject); +}; + +} + +#endif diff --git a/include/lldb/Host/OptionParser.h b/include/lldb/Host/OptionParser.h index ca83eeb1ed77..5aa7db5d34bf 100644 --- a/include/lldb/Host/OptionParser.h +++ b/include/lldb/Host/OptionParser.h @@ -16,18 +16,17 @@ struct option; namespace lldb_private { -typedef struct Option +struct OptionDefinition; + +struct Option { - // name of long option - const char *name; - // one of no_argument, required_argument, and optional_argument: - // whether option takes an argument - int has_arg; + // The definition of the option that this refers to. + const OptionDefinition *definition; // if not NULL, set *flag to val when option found int *flag; // if flag not NULL, value to set *flag to; else return value int val; -} Option; +}; class OptionParser { diff --git a/include/lldb/Host/Pipe.h b/include/lldb/Host/Pipe.h new file mode 100644 index 000000000000..b36c85cfbe87 --- /dev/null +++ b/include/lldb/Host/Pipe.h @@ -0,0 +1,83 @@ +//===-- Pipe.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_Pipe_h_ +#define liblldb_Pipe_h_ +#if defined(__cplusplus) + +#include +#include +#include + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Pipe Pipe.h "lldb/Host/Pipe.h" +/// @brief A class that abtracts unix style pipes. +/// +/// A class that abstracts the LLDB core from host pipe functionality. +//---------------------------------------------------------------------- +class Pipe +{ +public: + static int kInvalidDescriptor; + + Pipe(); + + ~Pipe(); + + bool + Open(); + + bool + IsValid() const; + + bool + ReadDescriptorIsValid() const; + + bool + WriteDescriptorIsValid() const; + + int + GetReadFileDescriptor() const; + + int + GetWriteFileDescriptor() const; + + // Close both descriptors + void + Close(); + + bool + CloseReadFileDescriptor(); + + bool + CloseWriteFileDescriptor(); + + int + ReleaseReadFileDescriptor(); + + int + ReleaseWriteFileDescriptor(); + + size_t + Read (void *buf, size_t size); + + size_t + Write (const void *buf, size_t size); +private: + int m_fds[2]; +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // liblldb_Pipe_h_ diff --git a/include/lldb/Host/Predicate.h b/include/lldb/Host/Predicate.h index 6ddf20b67c69..f0e83ea5894b 100644 --- a/include/lldb/Host/Predicate.h +++ b/include/lldb/Host/Predicate.h @@ -78,7 +78,7 @@ public: //------------------------------------------------------------------ /// Destructor. /// - /// Destrory the condition, mutex, and T objects. + /// Destroy the condition, mutex, and T objects. //------------------------------------------------------------------ ~Predicate () { @@ -112,7 +112,7 @@ public: /// The new value to set. /// /// @param[in] broadcast_type - /// A value indicating when and if to broadast. See the + /// A value indicating when and if to broadcast. See the /// PredicateBroadcastType enumeration for details. /// /// @see Predicate::Broadcast() @@ -140,7 +140,7 @@ public: /// The bits to set in \a m_value. /// /// @param[in] broadcast_type - /// A value indicating when and if to broadast. See the + /// A value indicating when and if to broadcast. See the /// PredicateBroadcastType enumeration for details. /// /// @see Predicate::Broadcast() @@ -168,7 +168,7 @@ public: /// The bits to clear in \a m_value. /// /// @param[in] broadcast_type - /// A value indicating when and if to broadast. See the + /// A value indicating when and if to broadcast. See the /// PredicateBroadcastType enumeration for details. /// /// @see Predicate::Broadcast() @@ -464,7 +464,7 @@ public: protected: //---------------------------------------------------------------------- - // pthread condition and mutex variable to controll access and allow + // pthread condition and mutex variable to control access and allow // blocking between the main thread and the spotlight index thread. //---------------------------------------------------------------------- T m_value; ///< The templatized value T that we are protecting access to @@ -477,7 +477,7 @@ private: /// Broadcast if needed. /// /// Check to see if we need to broadcast to our condition variable - /// depedning on the \a old_value and on the \a broadcast_type. + /// depending on the \a old_value and on the \a broadcast_type. /// /// If \a broadcast_type is eBroadcastNever, no broadcast will be /// sent. diff --git a/include/lldb/Host/Socket.h b/include/lldb/Host/Socket.h new file mode 100644 index 000000000000..0f3aa073001c --- /dev/null +++ b/include/lldb/Host/Socket.h @@ -0,0 +1,103 @@ +//===-- Socket.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_Host_Socket_h_ +#define liblldb_Host_Socket_h_ + +#include + +#include "lldb/lldb-private.h" + +#include "lldb/Core/Error.h" +#include "lldb/Host/IOObject.h" +#include "lldb/Host/Predicate.h" +#include "lldb/Host/SocketAddress.h" + +#ifdef _WIN32 +#include "lldb/Host/windows/windows.h" +#include +#include +#endif + +namespace llvm +{ + class StringRef; +} + +namespace lldb_private { + +#if defined(_MSC_VER) + typedef SOCKET NativeSocket; +#else + typedef int NativeSocket; +#endif + +class Socket : public IOObject +{ +public: + typedef enum + { + ProtocolTcp, + ProtocolUdp, + ProtocolUnixDomain + } SocketProtocol; + + static const NativeSocket kInvalidSocketValue; + + Socket(NativeSocket socket, SocketProtocol protocol, bool should_close); + ~Socket(); + + // Initialize a Tcp Socket object in listening mode. listen and accept are implemented + // separately because the caller may wish to manipulate or query the socket after it is + // initialized, but before entering a blocking accept. + static Error TcpListen(llvm::StringRef host_and_port, Socket *&socket, Predicate* predicate); + static Error TcpConnect(llvm::StringRef host_and_port, Socket *&socket); + static Error UdpConnect(llvm::StringRef host_and_port, Socket *&send_socket, Socket *&recv_socket); + static Error UnixDomainConnect(llvm::StringRef host_and_port, Socket *&socket); + static Error UnixDomainAccept(llvm::StringRef host_and_port, Socket *&socket); + + // Blocks on a listening socket until a connection is received. This method assumes that + // |this->m_socket| is a listening socket, created via either TcpListen() or via the native + // constructor that takes a NativeSocket, which itself was created via a call to |listen()| + Error BlockingAccept(llvm::StringRef host_and_port, Socket *&socket); + + 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; + + NativeSocket GetNativeSocket () const { return m_socket; } + 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 bool IsValid() const { return m_socket != kInvalidSocketValue; } + virtual WaitableHandle GetWaitableHandle(); + +protected: + static bool + DecodeHostAndPort (llvm::StringRef host_and_port, + std::string &host_str, + std::string &port_str, + int32_t& port, + Error *error_ptr); + + + SocketProtocol m_protocol; + NativeSocket m_socket; + SocketAddress m_udp_send_sockaddr; // Send address used for UDP connections. +}; +} + +#endif diff --git a/include/lldb/Host/SocketAddress.h b/include/lldb/Host/SocketAddress.h index 4dc62102103a..3598a42a82d0 100644 --- a/include/lldb/Host/SocketAddress.h +++ b/include/lldb/Host/SocketAddress.h @@ -16,7 +16,7 @@ #ifdef _WIN32 #include "lldb/Host/windows/windows.h" #include -#include +#include typedef ADDRESS_FAMILY sa_family_t; #else #include @@ -82,7 +82,7 @@ public: GetLength () const; //------------------------------------------------------------------ - // Get the mex length for the the largest socket address supported. + // Get the max length for the largest socket address supported. //------------------------------------------------------------------ static socklen_t GetMaxLength (); @@ -203,7 +203,7 @@ public: // Conversion operators to allow getting the contents of this class // as a pointer to the appropriate structure. This allows an instance // of this class to be used in calls that take one of the sockaddr - // structure variants without having to manally use the correct + // structure variants without having to manually use the correct // accessor function. //------------------------------------------------------------------ diff --git a/include/lldb/Host/Symbols.h b/include/lldb/Host/Symbols.h index 652a614e6355..d6c86333d709 100644 --- a/include/lldb/Host/Symbols.h +++ b/include/lldb/Host/Symbols.h @@ -50,7 +50,7 @@ public: // Locate the object and symbol file given a module specification. // // Locating the file can try to download the file from a corporate build - // respository, or using any other means necessary to locate both the + // repository, or using any other means necessary to locate both the // unstripped object file and the debug symbols. // The force_lookup argument controls whether the external program is called // unconditionally to find the symbol file, or if the user's settings are diff --git a/include/lldb/Host/Terminal.h b/include/lldb/Host/Terminal.h index 5ea88c515637..4a6017fc2eee 100644 --- a/include/lldb/Host/Terminal.h +++ b/include/lldb/Host/Terminal.h @@ -101,7 +101,7 @@ public: /// /// @param[in] save_process_group /// If \b true, save the process group settings, else do not - /// save the process group setttings for a TTY. + /// save the process group settings for a TTY. /// /// @return /// Returns \b true if \a fd describes a TTY and if the state diff --git a/include/lldb/Host/TimeValue.h b/include/lldb/Host/TimeValue.h index ba230045307f..1792d343a6a6 100644 --- a/include/lldb/Host/TimeValue.h +++ b/include/lldb/Host/TimeValue.h @@ -15,11 +15,7 @@ #ifndef _MSC_VER #include -// BEGIN: MinGW work around -#if !defined(_STRUCT_TIMESPEC) && !defined(HAVE_STRUCT_TIMESPEC) -#include -#endif -// END: MinGW work around + #endif // C++ Includes diff --git a/include/lldb/Host/freebsd/HostInfoFreeBSD.h b/include/lldb/Host/freebsd/HostInfoFreeBSD.h new file mode 100644 index 000000000000..1404a4b1525c --- /dev/null +++ b/include/lldb/Host/freebsd/HostInfoFreeBSD.h @@ -0,0 +1,29 @@ +//===-- HostInfoFreeBSD.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_Host_freebsd_HostInfoFreeBSD_h_ +#define lldb_Host_freebsd_HostInfoFreeBSD_h_ + +#include "lldb/Host/FileSpec.h" +#include "lldb/Host/posix/HostInfoPosix.h" + +namespace lldb_private +{ + +class HostInfoFreeBSD : public HostInfoPosix +{ + public: + static bool GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update); + static bool GetOSBuildString(std::string &s); + static bool GetOSKernelDescription(std::string &s); + static FileSpec GetProgramFileSpec(); +}; +} + +#endif diff --git a/include/lldb/Host/posix/HostInfoPosix.h b/include/lldb/Host/posix/HostInfoPosix.h new file mode 100644 index 000000000000..6e0dcbe48021 --- /dev/null +++ b/include/lldb/Host/posix/HostInfoPosix.h @@ -0,0 +1,40 @@ +//===-- HostInfoPosix.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_Host_posix_HostInfoPosix_h_ +#define lldb_Host_posix_HostInfoPosix_h_ + +#include "lldb/Host/HostInfoBase.h" + +namespace lldb_private +{ + +class HostInfoPosix : public HostInfoBase +{ + friend class HostInfoBase; + + public: + static size_t GetPageSize(); + static bool GetHostname(std::string &s); + static const char *LookupUserName(uint32_t uid, std::string &user_name); + static const char *LookupGroupName(uint32_t gid, std::string &group_name); + + static uint32_t GetUserID(); + static uint32_t GetGroupID(); + static uint32_t GetEffectiveUserID(); + static uint32_t GetEffectiveGroupID(); + + protected: + static bool ComputeSupportExeDirectory(FileSpec &file_spec); + static bool ComputeHeaderDirectory(FileSpec &file_spec); + static bool ComputePythonDirectory(FileSpec &file_spec); +}; +} + +#endif diff --git a/include/lldb/Host/posix/HostProcessPosix.h b/include/lldb/Host/posix/HostProcessPosix.h new file mode 100644 index 000000000000..aa003ee4845e --- /dev/null +++ b/include/lldb/Host/posix/HostProcessPosix.h @@ -0,0 +1,46 @@ +//===-- HostProcessPosix.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_Host_HostProcesPosix_h_ +#define lldb_Host_HostProcesPosix_h_ + +#include "lldb/lldb-types.h" +#include "lldb/Core/Error.h" +#include "lldb/Target/ProcessLaunchInfo.h" + +namespace lldb_private +{ + +class FileSpec; + +class HostProcessPosix +{ + public: + static const lldb::pid_t kInvalidProcessId; + + HostProcessPosix(); + ~HostProcessPosix(); + + Error Signal(int signo) const; + static Error Signal(lldb::pid_t pid, int signo); + + Error Create(lldb::pid_t pid); + Error Terminate(int signo); + Error GetMainModule(FileSpec &file_spec) const; + + lldb::pid_t GetProcessId() const; + bool IsRunning() const; + + private: + + lldb::pid_t m_pid; +}; +} + +#endif diff --git a/include/lldb/Interpreter/Args.h b/include/lldb/Interpreter/Args.h index 27feca63e4ad..06617f1e5926 100644 --- a/include/lldb/Interpreter/Args.h +++ b/include/lldb/Interpreter/Args.h @@ -293,7 +293,7 @@ public: /// A copy \a arg_cstr will be made. /// /// @param[in] arg_cstr - /// The argument to push on the front the the argument stack. + /// The argument to push on the front of the argument stack. /// /// @param[in] quote_char /// If the argument was originally quoted, put in the quote char here. @@ -308,7 +308,7 @@ public: /// Parse the arguments in the contained arguments. /// /// The arguments that are consumed by the argument parsing process - /// will be removed from the argument vector. The arguements that + /// will be removed from the argument vector. The arguments that /// get processed start at the second argument. The first argument /// is assumed to be the command and will not be touched. /// @@ -430,7 +430,7 @@ public: EncodeEscapeSequences (const char *src, std::string &dst); // ExpandEscapeSequences will change a string of possibly non-printable - // characters and expand them into text. So '\n' will turn into two chracters + // characters and expand them into text. So '\n' will turn into two characters // like "\n" which is suitable for human reading. When a character is not // printable and isn't one of the common in escape sequences listed in the // help for EncodeEscapeSequences, then it will be encoded as octal. Printable diff --git a/include/lldb/Interpreter/CommandCompletions.h b/include/lldb/Interpreter/CommandCompletions.h index c4ab1b61adeb..9df3041584ea 100644 --- a/include/lldb/Interpreter/CommandCompletions.h +++ b/include/lldb/Interpreter/CommandCompletions.h @@ -195,7 +195,7 @@ public: }; //---------------------------------------------------------------------- - // SouceFileCompleter implements the source file completer + // SourceFileCompleter implements the source file completer //---------------------------------------------------------------------- class SourceFileCompleter : public Completer { diff --git a/include/lldb/Interpreter/CommandInterpreter.h b/include/lldb/Interpreter/CommandInterpreter.h index bcb9b5538c84..c33d71a6dbbb 100644 --- a/include/lldb/Interpreter/CommandInterpreter.h +++ b/include/lldb/Interpreter/CommandInterpreter.h @@ -252,7 +252,7 @@ public: // This version just returns matches, and doesn't compute the substring. It is here so the // Help command can call it for the first argument. - // word_complete tells whether a the completions are considered a "complete" response (so the + // word_complete tells whether the completions are considered a "complete" response (so the // completer should complete the quote & put a space after the word. int @@ -332,6 +332,9 @@ public: void Initialize (); + + void + Clear (); void SetScriptLanguage (lldb::ScriptLanguage lang); @@ -476,12 +479,15 @@ protected: std::string &line); virtual ConstString - GetControlSequence (char ch) + IOHandlerGetControlSequence (char ch) { if (ch == 'd') return ConstString("quit\n"); return ConstString(); } + + virtual bool + IOHandlerInterrupt (IOHandler &io_handler); size_t GetProcessOutput (); diff --git a/include/lldb/Interpreter/CommandObject.h b/include/lldb/Interpreter/CommandObject.h index 8544fd9f9c3f..7bdf55a393d7 100644 --- a/include/lldb/Interpreter/CommandObject.h +++ b/include/lldb/Interpreter/CommandObject.h @@ -269,7 +269,7 @@ public: // // Ensures a valid register context (from the selected frame if there // is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx) - // is availble from m_exe_ctx prior to executing the command. If a + // is available from m_exe_ctx prior to executing the command. If a // target doesn't exist or is invalid, the command will fail and // CommandObject::GetInvalidRegContextDescription() will be returned as // the error. CommandObject subclasses can override the virtual function @@ -460,25 +460,37 @@ public: return NULL; } - CommandOverrideCallback - GetOverrideCallback () const + bool + HasOverrideCallback () const { - return m_command_override_callback; + return m_command_override_callback || m_deprecated_command_override_callback; } - void * - GetOverrideCallbackBaton () const + void + SetOverrideCallback (lldb::CommandOverrideCallback callback, void *baton) { - return m_command_override_baton; + m_deprecated_command_override_callback = callback; + m_command_override_baton = baton; } - + void - SetOverrideCallback (CommandOverrideCallback callback, void *baton) + SetOverrideCallback (lldb::CommandOverrideCallbackWithResult callback, void *baton) { m_command_override_callback = callback; m_command_override_baton = baton; } + bool + InvokeOverrideCallback (const char **argv, CommandReturnObject &result) + { + if (m_command_override_callback) + return m_command_override_callback(m_command_override_baton, argv, result); + else if (m_deprecated_command_override_callback) + return m_deprecated_command_override_callback(m_command_override_baton, argv); + else + return false; + } + virtual bool Execute (const char *args_string, CommandReturnObject &result) = 0; @@ -540,7 +552,8 @@ protected: bool m_is_alias; Flags m_flags; std::vector m_arguments; - CommandOverrideCallback m_command_override_callback; + lldb::CommandOverrideCallback m_deprecated_command_override_callback; + lldb::CommandOverrideCallbackWithResult m_command_override_callback; void * m_command_override_baton; // Helper function to populate IDs or ID ranges as the command argument data diff --git a/include/lldb/Interpreter/CommandOptionValidators.h b/include/lldb/Interpreter/CommandOptionValidators.h new file mode 100644 index 000000000000..6be247ad4b65 --- /dev/null +++ b/include/lldb/Interpreter/CommandOptionValidators.h @@ -0,0 +1,30 @@ +//===-- CommandOptionValidators.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_CommandOptionValidators_h_ +#define liblldb_CommandOptionValidators_h_ + +#include "lldb/lldb-private-types.h" + +namespace lldb_private { + +class Platform; +class ExecutionContext; + +class PosixPlatformCommandOptionValidator : public OptionValidator +{ + virtual bool IsValid(Platform &platform, const ExecutionContext &target) const; + virtual const char* ShortConditionString() const; + virtual const char* LongConditionString() const; +}; + +} // namespace lldb_private + + +#endif // liblldb_CommandOptionValidators_h_ diff --git a/include/lldb/Interpreter/CommandReturnObject.h b/include/lldb/Interpreter/CommandReturnObject.h index acd03992e5e6..b922e1731d7e 100644 --- a/include/lldb/Interpreter/CommandReturnObject.h +++ b/include/lldb/Interpreter/CommandReturnObject.h @@ -160,9 +160,17 @@ public: bool HasResult (); - bool GetDidChangeProcessState (); + bool + GetDidChangeProcessState (); + + void + SetDidChangeProcessState (bool b); - void SetDidChangeProcessState (bool b); + bool + GetInteractive () const; + + void + SetInteractive (bool b); private: enum @@ -176,6 +184,7 @@ private: lldb::ReturnStatus m_status; bool m_did_change_process_state; + bool m_interactive; // If true, then the input handle from the debugger will be hooked up }; } // namespace lldb_private diff --git a/include/lldb/Interpreter/Options.h b/include/lldb/Interpreter/Options.h index 2b4ac1190557..6ecf08d28e75 100644 --- a/include/lldb/Interpreter/Options.h +++ b/include/lldb/Interpreter/Options.h @@ -159,7 +159,7 @@ public: void OutputFormattedUsageText (Stream &strm, - const char *text, + const OptionDefinition &option_def, uint32_t output_max_columns); void @@ -301,6 +301,12 @@ public: int max_return_elements, bool &word_complete, StringList &matches); + + CommandInterpreter& + GetInterpreter() + { + return m_interpreter; + } protected: // This is a set of options expressed as indexes into the options table for this Option. diff --git a/include/lldb/Interpreter/PythonDataObjects.h b/include/lldb/Interpreter/PythonDataObjects.h index 63f1ad5f67bf..a1145b6f33d9 100644 --- a/include/lldb/Interpreter/PythonDataObjects.h +++ b/include/lldb/Interpreter/PythonDataObjects.h @@ -62,9 +62,11 @@ namespace lldb_private { { if (py_obj != m_py_obj) { - Py_XDECREF(m_py_obj); + if (Py_IsInitialized()) + Py_XDECREF(m_py_obj); m_py_obj = py_obj; - Py_XINCREF(m_py_obj); + if (Py_IsInitialized()) + Py_XINCREF(m_py_obj); } return true; } diff --git a/include/lldb/Interpreter/ScriptInterpreter.h b/include/lldb/Interpreter/ScriptInterpreter.h index 1d62c9b0fb52..5a8322f8eb4f 100644 --- a/include/lldb/Interpreter/ScriptInterpreter.h +++ b/include/lldb/Interpreter/ScriptInterpreter.h @@ -254,16 +254,20 @@ public: return error; } - virtual bool + virtual Error ExportFunctionDefinitionToInterpreter (StringList &function_def) { - return false; + Error error; + error.SetErrorString("not implemented"); + return error; } - virtual bool + virtual Error GenerateBreakpointCommandCallbackData (StringList &input, std::string& output) { - return false; + Error error; + error.SetErrorString("not implemented"); + return error; } virtual bool @@ -359,24 +363,44 @@ public: return lldb::ScriptInterpreterObjectSP(); } - virtual bool + virtual Error GenerateFunction(const char *signature, const StringList &input) { - return false; + Error error; + error.SetErrorString("unimplemented"); + return error; } virtual void - CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options, + CollectDataForBreakpointCommandCallback (std::vector &options, CommandReturnObject &result); virtual void CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options, CommandReturnObject &result); + /// Set the specified text as the callback for the breakpoint. + Error + SetBreakpointCommandCallback (std::vector &bp_options_vec, + const char *callback_text); + + virtual Error + SetBreakpointCommandCallback (BreakpointOptions *bp_options, + const char *callback_text) + { + Error error; + error.SetErrorString("unimplemented"); + return error; + } + + void + SetBreakpointCommandCallbackFunction (std::vector &bp_options_vec, + const char *function_name); + /// Set a one-liner as the callback for the breakpoint. virtual void - SetBreakpointCommandCallback (BreakpointOptions *bp_options, - const char *oneliner) + SetBreakpointCommandCallbackFunction (BreakpointOptions *bp_options, + const char *function_name) { return; } @@ -398,6 +422,12 @@ public: return false; } + virtual void + Clear () + { + // Clean up any ref counts to SBObjects that might be in global variables + } + virtual size_t CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor) { @@ -545,9 +575,6 @@ public: SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame, SWIGPython_GetDynamicSetting swig_plugin_get); - static void - TerminateInterpreter (); - virtual void ResetOutputFileHandle (FILE *new_fh) { } //By default, do nothing. diff --git a/include/lldb/Interpreter/ScriptInterpreterPython.h b/include/lldb/Interpreter/ScriptInterpreterPython.h index ba532808673f..14a62d67fde6 100644 --- a/include/lldb/Interpreter/ScriptInterpreterPython.h +++ b/include/lldb/Interpreter/ScriptInterpreterPython.h @@ -24,6 +24,8 @@ #include "lldb/Interpreter/PythonDataObjects.h" #include "lldb/Host/Terminal.h" +class IOHandlerPythonInterpreter; + namespace lldb_private { class ScriptInterpreterPython : @@ -56,7 +58,7 @@ public: ExecuteMultipleLines (const char *in_string, const ExecuteScriptOptions &options = ExecuteScriptOptions()); - bool + Error ExportFunctionDefinitionToInterpreter (StringList &function_def); bool @@ -130,10 +132,10 @@ public: lldb_private::CommandReturnObject& cmd_retobj, Error& error); - bool + Error GenerateFunction(const char *signature, const StringList &input); - bool + Error GenerateBreakpointCommandCallbackData (StringList &input, std::string& output); bool @@ -170,6 +172,9 @@ public: lldb::ScriptInterpreterObjectSP& callee_wrapper_sp, std::string& retval); + virtual void + Clear (); + virtual bool GetDocumentationForItem (const char* item, std::string& dest); @@ -220,17 +225,21 @@ public: AcquireInterpreterLock (); void - CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options, + CollectDataForBreakpointCommandCallback (std::vector &bp_options_vec, CommandReturnObject &result); void CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options, CommandReturnObject &result); - /// Set a Python one-liner as the callback for the breakpoint. - void + /// Set the callback body text into the callback for the breakpoint. + Error SetBreakpointCommandCallback (BreakpointOptions *bp_options, - const char *oneliner); + const char *callback_body); + + void + SetBreakpointCommandCallbackFunction (BreakpointOptions *bp_options, + const char *function_name); /// Set a one-liner as the callback for the watchpoint. void @@ -275,6 +284,19 @@ public: } + PyThreadState * + GetThreadState() + { + return m_command_thread_state; + } + + void + SetThreadState (PyThreadState *s) + { + if (s) + m_command_thread_state = s; + } + //---------------------------------------------------------------------- // IOHandlerDelegate //---------------------------------------------------------------------- @@ -335,7 +357,8 @@ protected: virtual ~ScriptInterpreterPythonObject() { - Py_XDECREF(m_object); + if (Py_IsInitialized()) + Py_XDECREF(m_object); m_object = NULL; } private: @@ -392,7 +415,7 @@ public: // FILE* m_tmp_fh; PyGILState_STATE m_GILState; }; -private: +protected: enum ActiveIOHandler { eIOHandlerNone, diff --git a/include/lldb/Symbol/Block.h b/include/lldb/Symbol/Block.h index 4a305e3cbbec..59671b00b3b8 100644 --- a/include/lldb/Symbol/Block.h +++ b/include/lldb/Symbol/Block.h @@ -29,13 +29,13 @@ namespace lldb_private { /// Block objects. The BlockList object contains a section offset /// address range, and Block objects contain one or more ranges /// which are offsets into that range. Blocks are can have discontiguous -/// ranges within the BlockList adress range, and each block can +/// ranges within the BlockList address range, and each block can /// contain child blocks each with their own sets of ranges. /// /// Each block has a variable list that represents local, argument, and /// static variables that are scoped to the block. /// -/// Inlined functions are representated by attaching a +/// Inlined functions are represented by attaching a /// InlineFunctionInfo shared pointer object to a block. Inlined /// functions are represented as named blocks. //---------------------------------------------------------------------- @@ -169,7 +169,7 @@ public: /// Dump the block contents. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. /// /// @param[in] base_addr /// The resolved start address of the Function's address @@ -348,7 +348,7 @@ public: /// Get const accessor for any inlined function information. /// /// @return - /// A comst pointer to any inlined function information, or NULL + /// A const pointer to any inlined function information, or NULL /// if this is a regular block. //------------------------------------------------------------------ const InlineFunctionInfo* @@ -455,7 +455,7 @@ public: GetRangeIndexContainingAddress (const Address& addr); //------------------------------------------------------------------ - // Since blocks might have multiple discontiguous addresss ranges, + // Since blocks might have multiple discontiguous address ranges, // we need to be able to get at any of the address ranges in a block. //------------------------------------------------------------------ bool @@ -477,7 +477,7 @@ protected: collection m_children; RangeList m_ranges; lldb::InlineFunctionInfoSP m_inlineInfoSP; ///< Inlined function information. - lldb::VariableListSP m_variable_list_sp; ///< The variable list for all local, static and paramter variables scoped to this block. + lldb::VariableListSP m_variable_list_sp; ///< The variable list for all local, static and parameter variables scoped to this block. bool m_parsed_block_info:1, ///< Set to true if this block and it's children have all been parsed m_parsed_block_variables:1, m_parsed_child_blocks:1; diff --git a/include/lldb/Symbol/ClangASTContext.h b/include/lldb/Symbol/ClangASTContext.h index 75fc07b480e1..2bb911c6e566 100644 --- a/include/lldb/Symbol/ClangASTContext.h +++ b/include/lldb/Symbol/ClangASTContext.h @@ -18,7 +18,6 @@ #include // Other libraries and framework includes -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallVector.h" #include "clang/AST/TemplateBase.h" @@ -44,6 +43,9 @@ public: ClangASTContext (const char *triple = NULL); ~ClangASTContext(); + + static ClangASTContext* + GetASTContext (clang::ASTContext* ast_ctx); clang::ASTContext * getASTContext(); @@ -72,8 +74,7 @@ public: clang::DiagnosticConsumer * getDiagnosticConsumer(); - clang::TargetOptions * - getTargetOptions(); + std::shared_ptr &getTargetOptions(); clang::TargetInfo * getTargetInfo(); @@ -94,7 +95,7 @@ public: HasExternalSource (); void - SetExternalSource (llvm::OwningPtr &ast_source_ap); + SetExternalSource (llvm::IntrusiveRefCntPtr &ast_source_ap); void RemoveExternalSource (); @@ -259,8 +260,8 @@ public: return 0; } - llvm::SmallVector names; - llvm::SmallVector args; + llvm::SmallVector names; + llvm::SmallVector args; }; clang::FunctionTemplateDecl * @@ -394,6 +395,29 @@ public: const Declaration &decl, const ClangASTType &integer_qual_type); + //------------------------------------------------------------------ + // Integer type functions + //------------------------------------------------------------------ + + ClangASTType + GetIntTypeFromBitSize (size_t bit_size, bool is_signed) + { + return GetIntTypeFromBitSize (getASTContext(), bit_size, is_signed); + } + + static ClangASTType + GetIntTypeFromBitSize (clang::ASTContext *ast, + size_t bit_size, bool is_signed); + + ClangASTType + GetPointerSizedIntType (bool is_signed) + { + return GetPointerSizedIntType (getASTContext(), is_signed); + } + + static ClangASTType + GetPointerSizedIntType (clang::ASTContext *ast, bool is_signed); + //------------------------------------------------------------------ // Floating point functions //------------------------------------------------------------------ @@ -419,7 +443,7 @@ protected: std::unique_ptr m_source_manager_ap; std::unique_ptr m_diagnostics_engine_ap; std::unique_ptr m_diagnostic_consumer_ap; - llvm::IntrusiveRefCntPtr m_target_options_rp; + std::shared_ptr m_target_options_rp; std::unique_ptr m_target_info_ap; std::unique_ptr m_identifier_table_ap; std::unique_ptr m_selector_table_ap; diff --git a/include/lldb/Symbol/ClangASTImporter.h b/include/lldb/Symbol/ClangASTImporter.h index dc6ce6b5b95b..ee4fcada8a6d 100644 --- a/include/lldb/Symbol/ClangASTImporter.h +++ b/include/lldb/Symbol/ClangASTImporter.h @@ -166,7 +166,7 @@ public: void BuildNamespaceMap (const clang::NamespaceDecl *decl); // - // Comleters for maps + // Completers for maps // class MapCompleter diff --git a/include/lldb/Symbol/ClangASTType.h b/include/lldb/Symbol/ClangASTType.h index 19b5d6ec6727..4dd17031e568 100644 --- a/include/lldb/Symbol/ClangASTType.h +++ b/include/lldb/Symbol/ClangASTType.h @@ -155,6 +155,9 @@ public: bool IsFunctionType (bool *is_variadic_ptr = NULL) const; + uint32_t + IsHomogeneousAggregate (ClangASTType* base_type_ptr) const; + size_t GetNumberOfFunctionArguments () const; @@ -210,7 +213,7 @@ public: IsPointerOrReferenceType (ClangASTType *pointee_type = NULL) const; bool - IsReferenceType (ClangASTType *pointee_type = NULL) const; + IsReferenceType (ClangASTType *pointee_type = nullptr, bool* is_rvalue = nullptr) const; bool IsScalarType () const; @@ -261,6 +264,9 @@ public: ConstString GetTypeName () const; + ConstString + GetDisplayTypeName () const; + uint32_t GetTypeInfo (ClangASTType *pointee_or_element_clang_type = NULL) const; @@ -309,7 +315,7 @@ public: clang::DeclContext *decl_ctx) const; ClangASTType - GetArrayElementType (uint64_t& stride) const; + GetArrayElementType (uint64_t *stride = nullptr) const; ClangASTType GetCanonicalType () const; @@ -317,7 +323,7 @@ public: ClangASTType GetFullyUnqualifiedType () const; - // Returns -1 if this isn't a function of if the fucntion doesn't have a prototype + // Returns -1 if this isn't a function of if the function doesn't have a prototype // Returns a value >= 0 if there is a prototype. int GetFunctionArgumentCount () const; @@ -420,7 +426,6 @@ public: ClangASTType GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, - const char *parent_name, size_t idx, bool transparent_pointers, bool omit_empty_base_classes, @@ -431,7 +436,8 @@ public: uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, - bool &child_is_deref_of_parent) const; + bool &child_is_deref_of_parent, + ValueObject *valobj) const; // Lookup a child given a name. This function will match base class names // and member member names in "clang_type" only, not descendants. @@ -641,6 +647,9 @@ public: AddressType address_type, StreamString &new_value); + clang::EnumDecl * + GetAsEnumDecl () const; + clang::RecordDecl * GetAsRecordDecl () const; diff --git a/include/lldb/Symbol/ClangExternalASTSourceCommon.h b/include/lldb/Symbol/ClangExternalASTSourceCommon.h index 72d77e74ca90..20c4b4354367 100644 --- a/include/lldb/Symbol/ClangExternalASTSourceCommon.h +++ b/include/lldb/Symbol/ClangExternalASTSourceCommon.h @@ -11,7 +11,7 @@ #define liblldb_ClangExternalASTSourceCommon_h // Clang headers like to use NDEBUG inside of them to enable/disable debug -// releated features using "#ifndef NDEBUG" preprocessor blocks to do one thing +// related features using "#ifndef NDEBUG" preprocessor blocks to do one thing // or another. This is bad because it means that if clang was built in release // mode, it assumes that you are building in release mode which is not always // the case. You can end up with functions that are defined as empty in header diff --git a/include/lldb/Symbol/CompileUnit.h b/include/lldb/Symbol/CompileUnit.h index 5de93670c5a7..f9238ebba18c 100644 --- a/include/lldb/Symbol/CompileUnit.h +++ b/include/lldb/Symbol/CompileUnit.h @@ -115,7 +115,7 @@ public: /// parse the debug information. /// /// @param[in] function_sp - /// A shared pointer to the a Function object. + /// A shared pointer to the Function object. //------------------------------------------------------------------ void AddFunction(lldb::FunctionSP& function_sp); @@ -178,7 +178,7 @@ public: /// Dump the compile unit contents to the stream \a s. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. /// /// @param[in] show_context /// If \b true, variables will dump their symbol context @@ -199,7 +199,7 @@ public: /// /// Multiple calls to this function can find all entries that match /// a given file and line by starting with \a start_idx equal to zero, - /// and calling this function back with the return valeu + 1. + /// and calling this function back with the return value + 1. /// /// @param[in] start_idx /// The zero based index at which to start looking for matches. @@ -377,7 +377,7 @@ public: /// using a LineEntry base address will be able to be resolved. /// /// @param[out] sc_list - /// A SymbolContext list class that willl get any matching + /// A SymbolContext list class that will get any matching /// entries appended to. /// /// @return diff --git a/include/lldb/Symbol/DWARFCallFrameInfo.h b/include/lldb/Symbol/DWARFCallFrameInfo.h index 13a14f8c4041..e67a5a2a8e2c 100644 --- a/include/lldb/Symbol/DWARFCallFrameInfo.h +++ b/include/lldb/Symbol/DWARFCallFrameInfo.h @@ -100,7 +100,7 @@ private: typedef std::shared_ptr CIESP; - typedef std::map cie_map_t; + typedef std::map cie_map_t; // Start address (file address), size, offset of FDE location // used for finding an FDE for a given File address; the start address field is diff --git a/include/lldb/Symbol/Declaration.h b/include/lldb/Symbol/Declaration.h index f014571595f0..73dede556eae 100644 --- a/include/lldb/Symbol/Declaration.h +++ b/include/lldb/Symbol/Declaration.h @@ -136,7 +136,7 @@ public: /// supplied stream \a s. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. //------------------------------------------------------------------ void Dump (Stream *s, bool show_fullpaths) const; @@ -236,7 +236,7 @@ public: /// Set accessor for the declaration file specification. /// /// @param[in] file_spec - /// The new declaration file specifciation. + /// The new declaration file specification. //------------------------------------------------------------------ void SetFile (const FileSpec& file_spec) diff --git a/include/lldb/Symbol/FuncUnwinders.h b/include/lldb/Symbol/FuncUnwinders.h index 7af063402289..0cf584239f95 100644 --- a/include/lldb/Symbol/FuncUnwinders.h +++ b/include/lldb/Symbol/FuncUnwinders.h @@ -21,7 +21,7 @@ public: // This is often sourced from the eh_frame exception handling info // 2. Unwinding from a non-call site (any location in the function) // This is often done by analyzing the function prologue assembly - // langauge instructions + // language instructions // 3. A fast unwind method for this function which only retrieves a // limited set of registers necessary to walk the stack // 4. An architectural default unwind plan when none of the above are @@ -31,7 +31,7 @@ public: // instructions are finished for migrating breakpoints past the // stack frame setup instructions when we don't have line table information. - FuncUnwinders (lldb_private::UnwindTable& unwind_table, const lldb::UnwindAssemblySP& assembly_profiler, AddressRange range); + FuncUnwinders (lldb_private::UnwindTable& unwind_table, AddressRange range); ~FuncUnwinders (); @@ -44,7 +44,7 @@ public: GetUnwindPlanAtCallSite (int current_offset); lldb::UnwindPlanSP - GetUnwindPlanAtNonCallSite (lldb_private::Thread& thread); + GetUnwindPlanAtNonCallSite (Target& target, lldb_private::Thread& thread, int current_offset); lldb::UnwindPlanSP GetUnwindPlanFastUnwind (lldb_private::Thread& Thread); @@ -76,8 +76,11 @@ public: InvalidateNonCallSiteUnwindPlan (lldb_private::Thread& Thread); private: + + lldb::UnwindAssemblySP + GetUnwindAssemblyProfiler (); + UnwindTable& m_unwind_table; - lldb::UnwindAssemblySP m_assembly_profiler; AddressRange m_range; Mutex m_mutex; diff --git a/include/lldb/Symbol/Function.h b/include/lldb/Symbol/Function.h index dcea24c0b632..5954cf520d70 100644 --- a/include/lldb/Symbol/Function.h +++ b/include/lldb/Symbol/Function.h @@ -24,7 +24,7 @@ namespace lldb_private { /// @class FunctionInfo Function.h "lldb/Symbol/Function.h" /// @brief A class that contains generic function information. /// -/// This provides generic function information that gets resused between +/// This provides generic function information that gets reused between /// inline functions and function types. //---------------------------------------------------------------------- class FunctionInfo @@ -94,7 +94,7 @@ public: /// supplied stream \a s. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. //------------------------------------------------------------------ void Dump (Stream *s, bool show_fullpaths) const; @@ -234,7 +234,7 @@ public: /// supplied stream \a s. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. //------------------------------------------------------------------ void Dump(Stream *s, bool show_fullpaths) const; @@ -316,14 +316,14 @@ private: /// (Function::m_type), and contains lexical blocks /// (Function::m_blocks). /// -/// The function inforation is split into a few pieces: +/// The function information is split into a few pieces: /// @li The concrete instance information /// @li The abstract information /// /// The abstract information is found in the function type (Type) that /// describes a function information, return type and parameter types. /// -/// The concreate information is the address range information and +/// The concrete information is the address range information and /// specific locations for an instance of this function. //---------------------------------------------------------------------- class Function : @@ -547,7 +547,7 @@ public: //------------------------------------------------------------------ /// Get accessor for the type that describes the function - /// return value type, and paramter types. + /// return value type, and parameter types. /// /// @return /// A type object pointer. @@ -557,7 +557,7 @@ public: //------------------------------------------------------------------ /// Get const accessor for the type that describes the function - /// return value type, and paramter types. + /// return value type, and parameter types. /// /// @return /// A const type object pointer. @@ -578,7 +578,7 @@ public: /// supplied stream \a s. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. /// /// @param[in] show_context /// If \b true, variables will dump their symbol context diff --git a/include/lldb/Symbol/LineEntry.h b/include/lldb/Symbol/LineEntry.h index d7750cd34916..082caea3b12f 100644 --- a/include/lldb/Symbol/LineEntry.h +++ b/include/lldb/Symbol/LineEntry.h @@ -59,7 +59,7 @@ struct LineEntry /// supplied stream \a s. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. /// /// @param[in] comp_unit /// The compile unit object that contains the support file @@ -98,7 +98,7 @@ struct LineEntry /// line entry to the supplied stream \a s. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. /// /// @param[in] comp_unit /// The compile unit object that contains the support file diff --git a/include/lldb/Symbol/LineTable.h b/include/lldb/Symbol/LineTable.h index 477c8455ded8..3e25ad17e94e 100644 --- a/include/lldb/Symbol/LineTable.h +++ b/include/lldb/Symbol/LineTable.h @@ -85,7 +85,7 @@ public: bool is_epilogue_begin, bool is_terminal_entry); - // Used to instantiate the LineSequence helper classw + // Used to instantiate the LineSequence helper class LineSequence* CreateLineSequenceContainer (); @@ -111,7 +111,7 @@ public: /// Dump all line entries in this line table to the stream \a s. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. /// /// @param[in] style /// The display style for the address. diff --git a/include/lldb/Symbol/ObjectContainer.h b/include/lldb/Symbol/ObjectContainer.h index 7fb686245057..679e8f03b67a 100644 --- a/include/lldb/Symbol/ObjectContainer.h +++ b/include/lldb/Symbol/ObjectContainer.h @@ -85,7 +85,7 @@ public: /// if it has been parsed. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. //------------------------------------------------------------------ virtual void Dump (Stream *s) const = 0; @@ -168,7 +168,7 @@ public: /// and the next plug-in can attempt to parse an object file. /// /// @return - /// Returns \b true if the header was parsed succesfully, \b + /// Returns \b true if the header was parsed successfully, \b /// false otherwise. //------------------------------------------------------------------ virtual bool diff --git a/include/lldb/Symbol/ObjectFile.h b/include/lldb/Symbol/ObjectFile.h index afa1f9b40902..bdc6ae8c9e81 100644 --- a/include/lldb/Symbol/ObjectFile.h +++ b/include/lldb/Symbol/ObjectFile.h @@ -21,6 +21,36 @@ #include "lldb/Symbol/UnwindTable.h" namespace lldb_private { + +class ObjectFileJITDelegate +{ +public: + ObjectFileJITDelegate () + { + } + + virtual + ~ObjectFileJITDelegate() + { + } + + virtual lldb::ByteOrder + GetByteOrder () const = 0; + + virtual uint32_t + GetAddressByteSize () const = 0; + + virtual void + PopulateSymtab (lldb_private::ObjectFile *obj_file, + lldb_private::Symtab &symtab) = 0; + + virtual void + PopulateSectionList (lldb_private::ObjectFile *obj_file, + lldb_private::SectionList §ion_list) = 0; + + virtual bool + GetArchitecture (lldb_private::ArchSpec &arch) = 0; +}; //---------------------------------------------------------------------- /// @class ObjectFile ObjectFile.h "lldb/Symbol/ObjectFile.h" @@ -32,23 +62,11 @@ namespace lldb_private { /// for an object file. /// /// Object files can be represented by the entire file, or by part of a -/// file. Examples of object files that are part of a file include -/// object files that contain information for multiple architectures in -/// the same file, or archive files that contain multiple objects -/// (ranlib archives) (possibly for multiple architectures as well). +/// file. An example of a partial file ObjectFile is one that contains +/// information for one of multiple architectures in the same file. /// -/// Object archive files (e.g. ranlib archives) can contain -/// multiple .o (object) files that must be selected by index or by name. -/// The number of objects that an ObjectFile contains can be determined -/// using the ObjectFile::GetNumObjects() const -/// function, and followed by a call to -/// ObjectFile::SelectObjectAtIndex (uint32_t) to change the currently -/// selected object. Objects can also be selected by name using the -/// ObjectFile::SelectObject(const char *) function. -/// -/// Once an architecture is selected (and an object is selected for -/// for archives), the object file information can be extracted from -/// this abstract class. +/// Once an architecture is selected the object file information can be +/// extracted from this abstract class. //---------------------------------------------------------------------- class ObjectFile: public std::enable_shared_from_this, @@ -68,6 +86,7 @@ public: eTypeObjectFile, /// An intermediate object file eTypeSharedLibrary, /// A shared library that can be used during execution eTypeStubLibrary, /// A library that can be linked against but not used for execution + eTypeJIT, /// JIT code that has symbols, sections and possibly debug info eTypeUnknown } Type; @@ -77,7 +96,8 @@ public: eStrataUnknown, eStrataUser, eStrataKernel, - eStrataRawImage + eStrataRawImage, + eStrataJIT } Strata; //------------------------------------------------------------------ @@ -91,7 +111,7 @@ public: const FileSpec *file_spec_ptr, lldb::offset_t file_offset, lldb::offset_t length, - lldb::DataBufferSP& data_sp, + const lldb::DataBufferSP& data_sp, lldb::offset_t data_offset); ObjectFile (const lldb::ModuleSP &module_sp, @@ -117,7 +137,7 @@ public: /// if it has been parsed. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. //------------------------------------------------------------------ virtual void Dump (Stream *s) = 0; @@ -354,6 +374,16 @@ public: virtual void CreateSections (SectionList &unified_section_list) = 0; + + //------------------------------------------------------------------ + /// Notify the ObjectFile that the file addresses in the Sections + /// for this module have been changed. + //------------------------------------------------------------------ + virtual void + SectionFileAddressesChanged () + { + } + //------------------------------------------------------------------ /// Gets the symbol table for the currently selected architecture /// (and object for archives). @@ -439,7 +469,7 @@ public: /// Gets the symbol file spec list for this object file. /// /// If the object file format contains a debug symbol file link, - /// the values will be return in the FileSpecList. + /// the values will be returned in the FileSpecList. /// /// @return /// Returns filespeclist. @@ -450,6 +480,21 @@ public: return FileSpecList(); } + //------------------------------------------------------------------ + /// Gets the file spec list of libraries re-exported by this object file. + /// + /// If the object file format has the notion of one library re-exporting the symbols from another, + /// the re-exported libraries will be returned in the FileSpecList. + /// + /// @return + /// Returns filespeclist. + //------------------------------------------------------------------ + virtual lldb_private::FileSpecList + GetReExportedLibraries () + { + return FileSpecList(); + } + //------------------------------------------------------------------ /// Sets the load address for an entire module, assuming a rigid /// slide of sections, if possible in the implementation. @@ -486,7 +531,7 @@ public: /// and the next plug-in can attempt to parse an object file. /// /// @return - /// Returns \b true if the header was parsed succesfully, \b + /// Returns \b true if the header was parsed successfully, \b /// false otherwise. //------------------------------------------------------------------ virtual bool @@ -751,17 +796,17 @@ public: size_t byte_size); size_t - GetData (off_t offset, size_t length, DataExtractor &data) const; + GetData (lldb::offset_t offset, size_t length, DataExtractor &data) const; size_t - CopyData (off_t offset, size_t length, void *dst) const; + CopyData (lldb::offset_t offset, size_t length, void *dst) const; - size_t + virtual size_t ReadSectionData (const Section *section, - off_t section_offset, + lldb::offset_t section_offset, void *dst, size_t dst_len) const; - size_t + virtual size_t ReadSectionData (const Section *section, DataExtractor& section_data) const; diff --git a/include/lldb/Symbol/Symbol.h b/include/lldb/Symbol/Symbol.h index db32ba373e42..0dd04b7112bc 100644 --- a/include/lldb/Symbol/Symbol.h +++ b/include/lldb/Symbol/Symbol.h @@ -92,6 +92,9 @@ public: return m_addr_range.GetBaseAddress(); } + lldb::addr_t + ResolveCallableAddress(Target &target) const; + const ConstString & GetName () const { @@ -135,7 +138,7 @@ public: SetReExportedSymbolSharedLibrary (const FileSpec &fspec); Symbol * - ResolveReExportedSymbol (Target &target); + ResolveReExportedSymbol (Target &target) const; uint32_t GetSiblingIndex () const; @@ -303,7 +306,15 @@ public: Stream &strm); protected: - + // This is the internal guts of ResolveReExportedSymbol, it assumes reexport_name is not null, and that module_spec + // is valid. We track the modules we've already seen to make sure we don't get caught in a cycle. + + Symbol * + ResolveReExportedSymbolInModuleSpec (Target &target, + ConstString &reexport_name, + lldb_private::ModuleSpec &module_spec, + lldb_private::ModuleList &seen_modules) const; + uint32_t m_uid; // User ID (usually the original symbol table index) uint16_t m_type_data; // data specific to m_type uint16_t m_type_data_resolved:1, // True if the data in m_type_data has already been calculated diff --git a/include/lldb/Symbol/SymbolContext.h b/include/lldb/Symbol/SymbolContext.h index 6fdd828bd9f2..c26b7a0b9a10 100644 --- a/include/lldb/Symbol/SymbolContext.h +++ b/include/lldb/Symbol/SymbolContext.h @@ -140,7 +140,7 @@ public: /// supplied stream \a s. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. //------------------------------------------------------------------ void Dump (Stream *s, Target *target) const; @@ -157,7 +157,7 @@ public: /// was stopped will be displayed. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. /// /// @param[in] so_addr /// The resolved section offset address. @@ -409,7 +409,7 @@ private: /// the result of a query that can contain a multiple results. Examples /// of such queries include: /// @li Looking up a function by name. -/// @li Finding all addressses for a specified file and line number. +/// @li Finding all addresses for a specified file and line number. //---------------------------------------------------------------------- class SymbolContextList { @@ -465,7 +465,7 @@ public: /// the list to the supplied stream \a s. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. //------------------------------------------------------------------ void Dump(Stream *s, Target *target) const; diff --git a/include/lldb/Symbol/SymbolContextScope.h b/include/lldb/Symbol/SymbolContextScope.h index 693cc0131e27..a02b4523a4c0 100644 --- a/include/lldb/Symbol/SymbolContextScope.h +++ b/include/lldb/Symbol/SymbolContextScope.h @@ -75,7 +75,7 @@ public: ~SymbolContextScope () {} //------------------------------------------------------------------ - /// Reconstruct the object's symbolc context into \a sc. + /// Reconstruct the object's symbol context into \a sc. /// /// The object should fill in as much of the SymbolContext as it /// can so function calls that require a symbol context can be made @@ -119,11 +119,11 @@ public: } //------------------------------------------------------------------ - /// Dump the object's symbolc context to the stream \a s. + /// Dump the object's symbol context to the stream \a s. /// /// The object should dump its symbol context to the stream \a s. /// This function is widely used in the DumpDebug and verbose output - /// for lldb objets. + /// for lldb objects. /// /// @param[in] s /// The stream to which to dump the object's symbol context. diff --git a/include/lldb/Symbol/SymbolFile.h b/include/lldb/Symbol/SymbolFile.h index 5b774e3a7d13..6df3d49fc464 100644 --- a/include/lldb/Symbol/SymbolFile.h +++ b/include/lldb/Symbol/SymbolFile.h @@ -67,7 +67,7 @@ public: /// Each symbol file gets to respond with a mask of abilities that /// it supports for each object file. This happens when we are /// trying to figure out which symbol file plug-in will get used - /// for a given object file. The plug-in that resoonds with the + /// for a given object file. The plug-in that responds with the /// best mix of "SymbolFile::Abilities" bits set, will get chosen to /// be the symbol file parser. This allows each plug-in to check for /// sections that contain data a symbol file plug-in would need. For @@ -152,6 +152,16 @@ public: ObjectFile* GetObjectFile() { return m_obj_file; } const ObjectFile* GetObjectFile() const { return m_obj_file; } + + //------------------------------------------------------------------ + /// Notify the SymbolFile that the file addresses in the Sections + /// for this module have been changed. + //------------------------------------------------------------------ + virtual void + SectionFileAddressesChanged () + { + } + protected: ObjectFile* m_obj_file; // The object file that symbols can be extracted from. diff --git a/include/lldb/Symbol/SymbolVendor.h b/include/lldb/Symbol/SymbolVendor.h index 0eeea4eb466b..82f902d4e07b 100644 --- a/include/lldb/Symbol/SymbolVendor.h +++ b/include/lldb/Symbol/SymbolVendor.h @@ -172,6 +172,13 @@ public: virtual void ClearSymtab (); + //------------------------------------------------------------------ + /// Notify the SymbolVendor that the file addresses in the Sections + /// for this module have been changed. + //------------------------------------------------------------------ + virtual void + SectionFileAddressesChanged (); + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ diff --git a/include/lldb/Symbol/Symtab.h b/include/lldb/Symbol/Symtab.h index 5dfb1c822d51..dc08333e22fb 100644 --- a/include/lldb/Symbol/Symtab.h +++ b/include/lldb/Symbol/Symtab.h @@ -46,6 +46,7 @@ public: Symbol * Resize (size_t count); uint32_t AddSymbol(const Symbol& symbol); size_t GetNumSymbols() const; + void SectionFileAddressesChanged (); void Dump(Stream *s, Target *target, SortOrder sort_type); void Dump(Stream *s, Target *target, std::vector& indexes) const; uint32_t GetIndexForSymbol (const Symbol *symbol) const; diff --git a/include/lldb/Symbol/Type.h b/include/lldb/Symbol/Type.h index da327439936c..eaa150e78ace 100644 --- a/include/lldb/Symbol/Type.h +++ b/include/lldb/Symbol/Type.h @@ -17,6 +17,8 @@ #include "lldb/Symbol/ClangASTType.h" #include "lldb/Symbol/Declaration.h" +#include "llvm/ADT/APSInt.h" + #include namespace lldb_private { @@ -103,6 +105,11 @@ public: void DumpTypeName(Stream *s); + // Since Type instances only keep a "SymbolFile *" internally, other classes + // like TypeImpl need make sure the module is still around before playing with + // Type instances. They can store a weak pointer to the Module; + lldb::ModuleSP + GetModule(); void GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_name); @@ -306,16 +313,18 @@ protected: // these classes are used to back the SBType* objects -class TypePair { -private: - ClangASTType clang_type; - lldb::TypeSP type_sp; - +class TypePair +{ public: - TypePair () : clang_type(), type_sp() {} + TypePair () : + clang_type(), + type_sp() + { + } + TypePair (ClangASTType type) : - clang_type(type), - type_sp() + clang_type(type), + type_sp() { } @@ -368,6 +377,16 @@ public: return ConstString (); } + ConstString + GetDisplayTypeName () const + { + if (type_sp) + return type_sp->GetClangForwardType().GetDisplayTypeName(); + if (clang_type) + return clang_type.GetDisplayTypeName(); + return ConstString(); + } + void SetType (ClangASTType type) { @@ -455,6 +474,17 @@ public: { return clang_type.GetASTContext(); } + + lldb::ModuleSP + GetModule () const + { + if (type_sp) + return type_sp->GetModule(); + return lldb::ModuleSP(); + } +protected: + ClangASTType clang_type; + lldb::TypeSP type_sp; }; class TypeImpl @@ -467,30 +497,30 @@ public: TypeImpl(const TypeImpl& rhs); - TypeImpl (lldb::TypeSP type_sp); + TypeImpl (const lldb::TypeSP &type_sp); - TypeImpl (ClangASTType clang_type); + TypeImpl (const ClangASTType &clang_type); - TypeImpl (lldb::TypeSP type_sp, ClangASTType dynamic); + TypeImpl (const lldb::TypeSP &type_sp, const ClangASTType &dynamic); - TypeImpl (ClangASTType clang_type, ClangASTType dynamic); + TypeImpl (const ClangASTType &clang_type, const ClangASTType &dynamic); - TypeImpl (TypePair pair, ClangASTType dynamic); + TypeImpl (const TypePair &pair, const ClangASTType &dynamic); void - SetType (lldb::TypeSP type_sp); + SetType (const lldb::TypeSP &type_sp); void - SetType (ClangASTType clang_type); + SetType (const ClangASTType &clang_type); void - SetType (lldb::TypeSP type_sp, ClangASTType dynamic); + SetType (const lldb::TypeSP &type_sp, const ClangASTType &dynamic); void - SetType (ClangASTType clang_type, ClangASTType dynamic); + SetType (const ClangASTType &clang_type, const ClangASTType &dynamic); void - SetType (TypePair pair, ClangASTType dynamic); + SetType (const TypePair &pair, const ClangASTType &dynamic); TypeImpl& operator = (const TypeImpl& rhs); @@ -511,6 +541,9 @@ public: ConstString GetName () const; + ConstString + GetDisplayTypeName () const; + TypeImpl GetPointerType () const; @@ -543,6 +576,11 @@ public: lldb::DescriptionLevel description_level); private: + + bool + CheckModule (lldb::ModuleSP &module_sp) const; + + lldb::ModuleWP m_module_wp; TypePair m_static_type; ClangASTType m_dynamic_type; }; @@ -772,7 +810,105 @@ private: TypePair m_type_pair; ConstString m_type_name; }; - + +class TypeEnumMemberImpl +{ +public: + TypeEnumMemberImpl () : + m_integer_type_sp(), + m_name(""), + m_value(), + m_valid(false) + { + } + + TypeEnumMemberImpl (const clang::EnumConstantDecl* enum_member_decl, + const lldb_private::ClangASTType& integer_type); + + TypeEnumMemberImpl (const TypeEnumMemberImpl& rhs) : + m_integer_type_sp(rhs.m_integer_type_sp), + m_name(rhs.m_name), + m_value(rhs.m_value), + m_valid(rhs.m_valid) + { + } + + TypeEnumMemberImpl& + operator = (const TypeEnumMemberImpl& rhs); + + bool + IsValid () + { + return m_valid; + } + + const ConstString & + GetName () const + { + return m_name; + } + + const lldb::TypeImplSP & + GetIntegerType () const + { + return m_integer_type_sp; + } + + uint64_t + GetValueAsUnsigned () const + { + return *m_value.getRawData(); + } + + int64_t + GetValueAsSigned () const + { + return (int64_t) *m_value.getRawData(); + } + +protected: + lldb::TypeImplSP m_integer_type_sp; + ConstString m_name; + llvm::APSInt m_value; + bool m_valid; +}; + +class TypeEnumMemberListImpl +{ +public: + TypeEnumMemberListImpl() : + m_content() + { + } + + void + Append (const lldb::TypeEnumMemberImplSP& type) + { + m_content.push_back(type); + } + + void + Append (const lldb_private::TypeEnumMemberListImpl& type_list); + + lldb::TypeEnumMemberImplSP + GetTypeEnumMemberAtIndex(size_t idx) + { + lldb::TypeEnumMemberImplSP enum_member; + if (idx < GetSize()) + enum_member = m_content[idx]; + return enum_member; + } + + size_t + GetSize() + { + return m_content.size(); + } + +private: + std::vector m_content; +}; + } // namespace lldb_private #endif // liblldb_Type_h_ diff --git a/include/lldb/Symbol/UnwindPlan.h b/include/lldb/Symbol/UnwindPlan.h index 6fc5ce042357..e1b146fe219e 100644 --- a/include/lldb/Symbol/UnwindPlan.h +++ b/include/lldb/Symbol/UnwindPlan.h @@ -365,6 +365,9 @@ public: void AppendRow (const RowSP& row_sp); + void + InsertRow (const RowSP& row_sp); + // Returns a pointer to the best row for the given offset into the function's instructions. // If offset is -1 it indicates that the function start is unknown - the final row in the UnwindPlan is returned. // In practice, the UnwindPlan for a function with no known start address will be the architectural default diff --git a/include/lldb/Symbol/UnwindTable.h b/include/lldb/Symbol/UnwindTable.h index 3a99eb463df4..3a89f9f1f3c6 100644 --- a/include/lldb/Symbol/UnwindTable.h +++ b/include/lldb/Symbol/UnwindTable.h @@ -13,7 +13,8 @@ #include -#include "lldb/lldb-private.h" +#include "lldb/lldb-private.h" +#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -42,6 +43,9 @@ public: lldb::FuncUnwindersSP GetUncachedFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc); + bool + GetArchitecture (lldb_private::ArchSpec &arch); + private: void Dump (Stream &s); @@ -56,8 +60,7 @@ private: collection m_unwinds; bool m_initialized; // delay some initialization until ObjectFile is set up - - lldb::UnwindAssemblySP m_assembly_profiler; + Mutex m_mutex; DWARFCallFrameInfo* m_eh_frame; diff --git a/include/lldb/Symbol/VariableList.h b/include/lldb/Symbol/VariableList.h index 08efd3d5b9a1..5f8f2a225650 100644 --- a/include/lldb/Symbol/VariableList.h +++ b/include/lldb/Symbol/VariableList.h @@ -60,10 +60,10 @@ public: AppendVariablesIfUnique(VariableList &var_list); // Returns the actual number of unique variables that were added to the - // list. "total_matches" will get updated with the actualy number of + // list. "total_matches" will get updated with the actually number of // matches that were found regardless of whether they were unique or not // to allow for error conditions when nothing is found, versus conditions - // where any varaibles that match "regex" were already in "var_list". + // where any variables that match "regex" were already in "var_list". size_t AppendVariablesIfUnique (const RegularExpression& regex, VariableList &var_list, diff --git a/include/lldb/Target/ABI.h b/include/lldb/Target/ABI.h index cc6c46cf0ec9..8809c0047fa0 100644 --- a/include/lldb/Target/ABI.h +++ b/include/lldb/Target/ABI.h @@ -20,24 +20,58 @@ #include "llvm/ADT/ArrayRef.h" +// forward define the llvm::Type class +namespace llvm { class Type; } + namespace lldb_private { class ABI : public PluginInterface { public: + + struct CallArgument + { + enum eType + { + HostPointer = 0, /* pointer to host data */ + TargetValue , /* value is on the target or literal */ + }; + eType type; /* value of eType */ + size_t size; /* size in bytes of this argument */ + union { + lldb::addr_t value; /* literal value */ + uint8_t *data; /* host data pointer */ + }; + }; + virtual ~ABI(); virtual size_t GetRedZoneSize () const = 0; - + virtual bool - PrepareTrivialCall (Thread &thread, - lldb::addr_t sp, - lldb::addr_t functionAddress, - lldb::addr_t returnAddress, - llvm::ArrayRef args) const = 0; + PrepareTrivialCall ( lldb_private::Thread &thread, + lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + llvm::ArrayRef args) const = 0; + + // Prepare trivial call used from ThreadPlanFunctionCallGDB + // AD: + // . Because i don't want to change other ABI's this is not declared pure virtual. + // The dummy implementation will simply fail. Only HexagonABI will currently + // use this method. + // . Two PrepareTrivialCall's is not good design so perhaps this should be combined. + // + virtual bool + PrepareTrivialCall ( lldb_private::Thread &thread, + lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + llvm::Type &prototype, + llvm::ArrayRef args) const; virtual bool GetArgumentValues (Thread &thread, @@ -48,16 +82,26 @@ public: ClangASTType &type, bool persistent = true) const; + // specialized to work with llvm IR types + lldb::ValueObjectSP + GetReturnValueObject (Thread &thread, + llvm::Type &type, + bool persistent = true) const; + // Set the Return value object in the current frame as though a function with virtual Error SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) = 0; protected: // This is the method the ABI will call to actually calculate the return value. - // Don't put it in a persistant value object, that will be done by the ABI::GetReturnValueObject. + // Don't put it in a persistent value object, that will be done by the ABI::GetReturnValueObject. virtual lldb::ValueObjectSP - GetReturnValueObjectImpl (Thread &thread, - ClangASTType &type) const = 0; + GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type) const = 0; + + // specialized to work with llvm IR types + virtual lldb::ValueObjectSP + GetReturnValueObjectImpl( Thread &thread, llvm::Type &ir_type ) const; + public: virtual bool CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan) = 0; @@ -108,7 +152,6 @@ public: virtual bool FunctionCallsChangeCFA () = 0; - bool GetRegisterInfoByName (const ConstString &name, RegisterInfo &info); diff --git a/include/lldb/Target/CPPLanguageRuntime.h b/include/lldb/Target/CPPLanguageRuntime.h index 98a4ab88cb25..daf8a67d2a9d 100644 --- a/include/lldb/Target/CPPLanguageRuntime.h +++ b/include/lldb/Target/CPPLanguageRuntime.h @@ -136,7 +136,7 @@ public: static bool StripNamespacesFromVariableName (const char *name, const char *&base_name_start, const char *&base_name_end); - // in some cases, compilers will output different names for one same type. when tht happens, it might be impossible + // in some cases, compilers will output different names for one same type. when that happens, it might be impossible // to construct SBType objects for a valid type, because the name that is available is not the same as the name that // can be used as a search key in FindTypes(). the equivalents map here is meant to return possible alternative names // for a type through which a search can be conducted. Currently, this is only enabled for C++ but can be extended diff --git a/include/lldb/Target/ExecutionContext.h b/include/lldb/Target/ExecutionContext.h index f825c2e72e6d..50f2beaf949b 100644 --- a/include/lldb/Target/ExecutionContext.h +++ b/include/lldb/Target/ExecutionContext.h @@ -18,10 +18,10 @@ /// variable value from a data section in one of the object files in /// a target). There are two types of objects that hold onto execution /// contexts: ExecutionContextRef and ExecutionContext. Both of these -/// objects are deascribed below. +/// objects are described below. /// /// Not all objects in an ExectionContext objects will be valid. If you want -/// to refer stronly (ExectionContext) or weakly (ExectionContextRef) to +/// to refer strongly (ExectionContext) or weakly (ExectionContextRef) to /// a process, then only the process and target references will be valid. /// For threads, only the thread, process and target references will be /// filled in. For frames, all of the objects will be filled in. @@ -49,7 +49,7 @@ namespace lldb_private { /// context that might change over time. For example, if an object wants /// to refer to a stack frame, it should hold onto an ExecutionContextRef /// to a frame object. The backing object that represents the stack frame -/// might change over time and instaces of this object can track the logical +/// might change over time and instances of this object can track the logical /// object that refers to a frame even if it does change. /// /// These objects also don't keep execution objects around longer than they @@ -64,7 +64,7 @@ namespace lldb_private { /// don't keep these objects around, they are safe to keep around. /// /// The general rule of thumb is all long lived objects that want to -/// refer to execution contexts should use ExecutionContextRef objcts. +/// refer to execution contexts should use ExecutionContextRef objects. /// The ExecutionContext class is used to temporarily get shared /// pointers to any execution context objects that are still around /// so they are guaranteed to exist during a function that requires the @@ -89,7 +89,7 @@ public: /// Construct using an ExecutionContext object that might be NULL. /// /// If \a exe_ctx_ptr is valid, then make weak references to any - /// valid objects in the ExecutionContext, othewise no weak + /// valid objects in the ExecutionContext, otherwise no weak /// references to any execution context objects will be made. //------------------------------------------------------------------ ExecutionContextRef (const ExecutionContext *exe_ctx_ptr); @@ -104,7 +104,7 @@ public: //------------------------------------------------------------------ /// Assignment operator /// - /// Copy all weak refernces in \a rhs. + /// Copy all weak references in \a rhs. //------------------------------------------------------------------ ExecutionContextRef & operator =(const ExecutionContextRef &rhs); @@ -112,7 +112,7 @@ public: //------------------------------------------------------------------ /// Assignment operator from a ExecutionContext /// - /// Make weak refernces to any stringly referenced objects in \a exe_ctx. + /// Make weak references to any strongly referenced objects in \a exe_ctx. //------------------------------------------------------------------ ExecutionContextRef & operator =(const ExecutionContext &exe_ctx); @@ -129,13 +129,13 @@ public: /// Construct using an execution context scope. /// /// If the ExecutionContextScope object is valid and refers to a frame, - /// make weak refernces too the frame, thread, process and target. + /// make weak references too the frame, thread, process and target. /// If the ExecutionContextScope object is valid and refers to a thread, - /// make weak refernces too the thread, process and target. + /// make weak references too the thread, process and target. /// If the ExecutionContextScope object is valid and refers to a process, - /// make weak refernces too the process and target. + /// make weak references too the process and target. /// If the ExecutionContextScope object is valid and refers to a target, - /// make weak refernces too the target. + /// make weak references too the target. //------------------------------------------------------------------ ExecutionContextRef (ExecutionContextScope *exe_scope); @@ -143,13 +143,13 @@ public: /// Construct using an execution context scope. /// /// If the ExecutionContextScope object refers to a frame, - /// make weak refernces too the frame, thread, process and target. + /// make weak references too the frame, thread, process and target. /// If the ExecutionContextScope object refers to a thread, - /// make weak refernces too the thread, process and target. + /// make weak references too the thread, process and target. /// If the ExecutionContextScope object refers to a process, - /// make weak refernces too the process and target. + /// make weak references too the process and target. /// If the ExecutionContextScope object refers to a target, - /// make weak refernces too the target. + /// make weak references too the target. //------------------------------------------------------------------ ExecutionContextRef (ExecutionContextScope &exe_scope); @@ -302,8 +302,8 @@ public: //------------------------------------------------------------------ /// Returns true if this object has a weak reference to a thread. - /// The return value is only an indication of wether this object has - /// a weak reference and does not indicate wether the weak rerference + /// The return value is only an indication of whether this object has + /// a weak reference and does not indicate whether the weak reference /// is valid or not. //------------------------------------------------------------------ bool @@ -314,8 +314,8 @@ public: //------------------------------------------------------------------ /// Returns true if this object has a weak reference to a frame. - /// The return value is only an indication of wether this object has - /// a weak reference and does not indicate wether the weak rerference + /// The return value is only an indication of whether this object has + /// a weak reference and does not indicate whether the weak reference /// is valid or not. //------------------------------------------------------------------ bool diff --git a/include/lldb/Target/ExecutionContextScope.h b/include/lldb/Target/ExecutionContextScope.h index 7ba40971af2c..4a1b17d5a114 100644 --- a/include/lldb/Target/ExecutionContextScope.h +++ b/include/lldb/Target/ExecutionContextScope.h @@ -29,7 +29,7 @@ namespace lldb_private { /// ExecutionContext object in the object state. Examples of these /// objects include: Process, Thread, RegisterContext and StackFrame. /// -/// Bbjects can contain a valid pointer to an instance of this so they +/// Objects can contain a valid pointer to an instance of this so they /// can reconstruct the execution context. /// /// Objects that adhere to this protocol can reconstruct enough of a diff --git a/include/lldb/Target/FileAction.h b/include/lldb/Target/FileAction.h new file mode 100644 index 000000000000..db84c0ef468c --- /dev/null +++ b/include/lldb/Target/FileAction.h @@ -0,0 +1,68 @@ +//===-- ProcessLaunchInfo.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_Target_FileAction_h +#define liblldb_Target_FileAction_h + +#include + +namespace lldb_private +{ + +class FileAction +{ + public: + enum Action + { + eFileActionNone, + eFileActionClose, + eFileActionDuplicate, + eFileActionOpen + }; + + FileAction(); + + void Clear(); + + bool Close(int fd); + + bool Duplicate(int fd, int dup_fd); + + bool Open(int fd, const char *path, bool read, bool write); + + int + GetFD() const + { + return m_fd; + } + + Action + GetAction() const + { + return m_action; + } + + int + GetActionArgument() const + { + return m_arg; + } + + const char *GetPath() const; + + protected: + Action m_action; // The action for this file + int m_fd; // An existing file descriptor + int m_arg; // oflag for eFileActionOpen*, dup_fd for eFileActionDuplicate + std::string m_path; // A file path to use for opening after fork or posix_spawn +}; + +} // namespace lldb_private + +#endif diff --git a/include/lldb/Target/JITLoader.h b/include/lldb/Target/JITLoader.h new file mode 100644 index 000000000000..c15ae5a876f1 --- /dev/null +++ b/include/lldb/Target/JITLoader.h @@ -0,0 +1,90 @@ +//===-- JITLoader.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_JITLoader_h_ +#define liblldb_JITLoader_h_ + +#include + +#include "lldb/Core/PluginInterface.h" +#include "lldb/Target/JITLoaderList.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class JITLoader JITLoader.h "lldb/Target/JITLoader.h" +/// @brief A plug-in interface definition class for JIT loaders. +/// +/// Plugins of this kind listen for code generated at runtime in the +/// target. They are very similar to dynamic loader, with the difference +/// that they do not have information about the target's dyld and +/// that there may be multiple JITLoader plugins per process, while +/// there is at most one DynamicLoader. +//---------------------------------------------------------------------- +class JITLoader : + public PluginInterface +{ +public: + //------------------------------------------------------------------ + /// Find a JIT loader plugin for a given process. + /// + /// Scans the installed DynamicLoader plug-ins and tries to find + /// all applicable instances for the current process. + /// + /// @param[in] process + /// The process for which to try and locate a JIT loader + /// plug-in instance. + /// + //------------------------------------------------------------------ + static void + LoadPlugins (Process *process, lldb_private::JITLoaderList &list); + + //------------------------------------------------------------------ + /// Construct with a process. + //------------------------------------------------------------------ + JITLoader (Process *process); + + virtual + ~JITLoader (); + + //------------------------------------------------------------------ + /// Called after attaching a process. + /// + /// Allow JITLoader plug-ins to execute some code after + /// attaching to a process. + //------------------------------------------------------------------ + virtual void + DidAttach () = 0; + + //------------------------------------------------------------------ + /// Called after launching a process. + /// + /// Allow JITLoader plug-ins to execute some code after + /// the process has stopped for the first time on launch. + //------------------------------------------------------------------ + virtual void + DidLaunch () = 0; + + //------------------------------------------------------------------ + /// Called after a new shared object has been loaded so that it can + /// be probed for JIT entry point hooks. + //------------------------------------------------------------------ + virtual void + ModulesDidLoad (lldb_private::ModuleList &module_list) = 0; + +protected: + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + Process* m_process; +}; + +} // namespace lldb_private + +#endif // liblldb_JITLoader_h_ diff --git a/include/lldb/Target/JITLoaderList.h b/include/lldb/Target/JITLoaderList.h new file mode 100644 index 000000000000..f933a61e9952 --- /dev/null +++ b/include/lldb/Target/JITLoaderList.h @@ -0,0 +1,60 @@ +//===-- JITLoaderList.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_JITLoaderList_h_ +#define liblldb_JITLoaderList_h_ + +#include + +#include "lldb/lldb-forward.h" +#include "lldb/Host/Mutex.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class JITLoaderList JITLoaderList.h "lldb/Target/JITLoaderList.h" +/// +/// Class used by the Process to hold a list of its JITLoaders. +//---------------------------------------------------------------------- +class JITLoaderList +{ +public: + + JITLoaderList(); + ~JITLoaderList(); + + void + Append (const lldb::JITLoaderSP &jit_loader_sp); + + void + Remove (const lldb::JITLoaderSP &jit_loader_sp); + + size_t + GetSize() const; + + lldb::JITLoaderSP + GetLoaderAtIndex (size_t idx); + + void + DidLaunch(); + + void + DidAttach(); + + void + ModulesDidLoad (ModuleList &module_list); + +private: + std::vector m_jit_loaders_vec; + lldb_private::Mutex m_jit_loaders_mutex; +}; + +} // namespace lldb_private + +#endif // liblldb_JITLoaderList_h_ diff --git a/include/lldb/Target/MemoryRegionInfo.h b/include/lldb/Target/MemoryRegionInfo.h new file mode 100644 index 000000000000..0726ad15e876 --- /dev/null +++ b/include/lldb/Target/MemoryRegionInfo.h @@ -0,0 +1,104 @@ +//===-- MemoryRegionInfo.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_MemoryRegionInfo_h +#define lldb_MemoryRegionInfo_h + +#include "lldb/Core/RangeMap.h" +#include "lldb/Utility/Range.h" + +namespace lldb_private +{ + class MemoryRegionInfo + { + public: + typedef Range RangeType; + + enum OptionalBool { + eDontKnow = -1, + eNo = 0, + eYes = 1 + }; + + MemoryRegionInfo () : + m_range (), + m_read (eDontKnow), + m_write (eDontKnow), + m_execute (eDontKnow) + { + } + + ~MemoryRegionInfo () + { + } + + RangeType & + GetRange() + { + return m_range; + } + + void + Clear() + { + m_range.Clear(); + m_read = m_write = m_execute = eDontKnow; + } + + const RangeType & + GetRange() const + { + return m_range; + } + + OptionalBool + GetReadable () const + { + return m_read; + } + + OptionalBool + GetWritable () const + { + return m_write; + } + + OptionalBool + GetExecutable () const + { + return m_execute; + } + + void + SetReadable (OptionalBool val) + { + m_read = val; + } + + void + SetWritable (OptionalBool val) + { + m_write = val; + } + + void + SetExecutable (OptionalBool val) + { + m_execute = val; + } + + protected: + RangeType m_range; + OptionalBool m_read; + OptionalBool m_write; + OptionalBool m_execute; + }; +} + +#endif // #ifndef lldb_MemoryRegionInfo_h diff --git a/include/lldb/Target/NativeRegisterContext.h b/include/lldb/Target/NativeRegisterContext.h new file mode 100644 index 000000000000..fa4ab013f234 --- /dev/null +++ b/include/lldb/Target/NativeRegisterContext.h @@ -0,0 +1,190 @@ +//===-- NativeRegisterContext.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_NativeRegisterContext_h_ +#define liblldb_NativeRegisterContext_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class NativeThreadProtocol; + +class NativeRegisterContext: + public std::enable_shared_from_this +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + NativeRegisterContext (NativeThreadProtocol &thread, uint32_t concrete_frame_idx); + + virtual + ~NativeRegisterContext (); + + // void + // InvalidateIfNeeded (bool force); + + //------------------------------------------------------------------ + // Subclasses must override these functions + //------------------------------------------------------------------ + // virtual void + // InvalidateAllRegisters () = 0; + + virtual uint32_t + GetRegisterCount () const = 0; + + virtual const RegisterInfo * + GetRegisterInfoAtIndex (uint32_t reg) const = 0; + + const char * + GetRegisterSetNameForRegisterAtIndex (uint32_t reg_index) const; + + virtual uint32_t + GetRegisterSetCount () const = 0; + + virtual const RegisterSet * + GetRegisterSet (uint32_t set_index) const = 0; + + virtual Error + ReadRegister (const RegisterInfo *reg_info, RegisterValue ®_value) = 0; + + virtual Error + WriteRegister (const RegisterInfo *reg_info, const RegisterValue ®_value) = 0; + + virtual Error + ReadAllRegisterValues (lldb::DataBufferSP &data_sp) = 0; + + virtual Error + WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) = 0; + + uint32_t + ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const; + + //------------------------------------------------------------------ + // Subclasses can override these functions if desired + //------------------------------------------------------------------ + virtual uint32_t + NumSupportedHardwareBreakpoints (); + + virtual uint32_t + SetHardwareBreakpoint (lldb::addr_t addr, size_t size); + + virtual bool + ClearHardwareBreakpoint (uint32_t hw_idx); + + virtual uint32_t + NumSupportedHardwareWatchpoints (); + + virtual uint32_t + SetHardwareWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags); + + virtual bool + ClearHardwareWatchpoint (uint32_t hw_index); + + virtual bool + HardwareSingleStep (bool enable); + + virtual Error + ReadRegisterValueFromMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr, lldb::addr_t src_len, RegisterValue ®_value); + + virtual Error + WriteRegisterValueToMemory (const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, lldb::addr_t dst_len, const RegisterValue ®_value); + + //------------------------------------------------------------------ + // Subclasses should not override these + //------------------------------------------------------------------ + virtual lldb::tid_t + GetThreadID() const; + + virtual NativeThreadProtocol & + GetThread () + { + return m_thread; + } + + const RegisterInfo * + GetRegisterInfoByName (const char *reg_name, uint32_t start_idx = 0); + + const RegisterInfo * + GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num); + + lldb::addr_t + GetPC (lldb::addr_t fail_value = LLDB_INVALID_ADDRESS); + + Error + SetPC (lldb::addr_t pc); + + lldb::addr_t + GetSP (lldb::addr_t fail_value = LLDB_INVALID_ADDRESS); + + Error + SetSP (lldb::addr_t sp); + + lldb::addr_t + GetFP (lldb::addr_t fail_value = LLDB_INVALID_ADDRESS); + + Error + SetFP (lldb::addr_t fp); + + const char * + GetRegisterName (uint32_t reg); + + lldb::addr_t + GetReturnAddress (lldb::addr_t fail_value = LLDB_INVALID_ADDRESS); + + lldb::addr_t + GetFlags (lldb::addr_t fail_value = 0); + + lldb::addr_t + ReadRegisterAsUnsigned (uint32_t reg, lldb::addr_t fail_value); + + lldb::addr_t + ReadRegisterAsUnsigned (const RegisterInfo *reg_info, lldb::addr_t fail_value); + + Error + WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval); + + Error + WriteRegisterFromUnsigned (const RegisterInfo *reg_info, uint64_t uval); + + // uint32_t + // GetStopID () const + // { + // return m_stop_id; + // } + + // void + // SetStopID (uint32_t stop_id) + // { + // m_stop_id = stop_id; + // } + +protected: + //------------------------------------------------------------------ + // Classes that inherit from RegisterContext can see and modify these + //------------------------------------------------------------------ + NativeThreadProtocol &m_thread; // The thread that this register context belongs to. + uint32_t m_concrete_frame_idx; // The concrete frame index for this register context + // uint32_t m_stop_id; // The stop ID that any data in this context is valid for + +private: + //------------------------------------------------------------------ + // For RegisterContext only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (NativeRegisterContext); +}; + +} // namespace lldb_private + +#endif // liblldb_NativeRegisterContext_h_ diff --git a/include/lldb/Target/NativeRegisterContextRegisterInfo.h b/include/lldb/Target/NativeRegisterContextRegisterInfo.h new file mode 100644 index 000000000000..5631005ca56e --- /dev/null +++ b/include/lldb/Target/NativeRegisterContextRegisterInfo.h @@ -0,0 +1,44 @@ +//===-- NativeRegisterContextRegisterInfo.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_NativeRegisterContextRegisterInfo_h +#define lldb_NativeRegisterContextRegisterInfo_h + +#include + +#include "NativeRegisterContext.h" +#include "Plugins/Process/Utility/RegisterInfoInterface.h" + +namespace lldb_private +{ + class NativeRegisterContextRegisterInfo: public NativeRegisterContext + { + public: + /// + /// Construct a NativeRegisterContextRegisterInfo, taking ownership + /// of the register_info_interface pointer. + /// + NativeRegisterContextRegisterInfo (NativeThreadProtocol &thread, + uint32_t concrete_frame_idx, + RegisterInfoInterface *register_info_interface); + + uint32_t + GetRegisterCount () const override; + + const RegisterInfo * + GetRegisterInfoAtIndex (uint32_t reg_index) const override; + + const RegisterInfoInterface& + GetRegisterInfoInterface () const; + + private: + std::unique_ptr m_register_info_interface_up; + }; +} +#endif diff --git a/include/lldb/Target/ObjCLanguageRuntime.h b/include/lldb/Target/ObjCLanguageRuntime.h index 7bac57256444..12254f942e42 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/Symbol/ClangASTType.h" #include "lldb/Symbol/Type.h" #include "lldb/Symbol/TypeVendor.h" #include "lldb/Target/LanguageRuntime.h" @@ -221,7 +222,7 @@ public: Describe (std::function const &superclass_func, std::function const &instance_method_func, std::function const &class_method_func, - std::function const &ivar_func) + std::function const &ivar_func) const { return false; } @@ -238,6 +239,25 @@ public: m_type_wp = type_sp; } + struct iVarDescriptor { + ConstString m_name; + ClangASTType m_type; + uint64_t m_size; + int32_t m_offset; + }; + + virtual size_t + GetNumIVars () + { + return 0; + } + + virtual iVarDescriptor + GetIVarAtIndex (size_t idx) + { + return iVarDescriptor(); + } + protected: bool IsPointerValid (lldb::addr_t value, @@ -252,6 +272,25 @@ public: lldb::TypeWP m_type_wp; }; + class EncodingToType + { + public: + virtual ClangASTType RealizeType (ClangASTContext& ast_ctx, const char* name, bool allow_unknownanytype); + virtual ClangASTType RealizeType (const char* name, bool allow_unknownanytype); + + virtual ClangASTType RealizeType (clang::ASTContext& ast_ctx, const char* name, bool allow_unknownanytype) = 0; + + virtual ~EncodingToType(); + + protected: + std::unique_ptr m_scratch_ast_ctx_ap; + }; + + typedef std::shared_ptr EncodingToTypeSP; + + virtual EncodingToTypeSP + GetEncodingToType (); + virtual ClassDescriptorSP GetClassDescriptor (ValueObject& in_value); diff --git a/include/lldb/Target/PathMappingList.h b/include/lldb/Target/PathMappingList.h index b5bcbbfd768f..17185cb68495 100644 --- a/include/lldb/Target/PathMappingList.h +++ b/include/lldb/Target/PathMappingList.h @@ -78,7 +78,7 @@ public: bool notify); bool - Remove (off_t index, bool notify); + Remove (size_t index, bool notify); bool Remove (const ConstString &path, bool notify); diff --git a/include/lldb/Target/Platform.h b/include/lldb/Target/Platform.h index 80011fd120de..e3d6abe3f398 100644 --- a/include/lldb/Target/Platform.h +++ b/include/lldb/Target/Platform.h @@ -18,6 +18,7 @@ // Other libraries and framework includes // Project includes +#include "lldb/lldb-private-forward.h" #include "lldb/lldb-public.h" #include "lldb/Core/ArchSpec.h" #include "lldb/Core/ConstString.h" @@ -25,6 +26,10 @@ #include "lldb/Interpreter/Options.h" #include "lldb/Host/Mutex.h" +// TODO pull NativeDelegate class out of NativeProcessProtocol so we +// can just forward ref the NativeDelegate rather than include it here. +#include "../../../source/Host/common/NativeProcessProtocol.h" + namespace lldb_private { //---------------------------------------------------------------------- @@ -174,13 +179,13 @@ namespace lldb_private { /// m_arch - The architecture we are looking for when resolving /// the symbol file. /// m_uuid - The UUID of the executable and symbol file. This - /// can often be used to match up an exectuable with + /// can often be used to match up an executable with /// a symbol file, or resolve an symbol file in a /// symbol file bundle. /// /// @param[out] sym_file /// The resolved symbol file spec if the returned error - /// indicates succes. + /// indicates success. /// /// @return /// Returns an error that describes success or failure. @@ -215,7 +220,7 @@ namespace lldb_private { bool GetOSKernelDescription (std::string &s); - // Returns the the name of the platform + // Returns the name of the platform ConstString GetName (); @@ -241,7 +246,7 @@ namespace lldb_private { // // Remote classes must be connected for this to succeed. Local // subclasses don't need to override this function as it will just - // call the Host::GetOSVersion(). + // call the HostInfo::GetOSVersion(). //------------------------------------------------------------------ virtual bool GetRemoteOSVersion () @@ -326,7 +331,8 @@ namespace lldb_private { //---------------------------------------------------------------------- virtual FileSpecList LocateExecutableScriptingResources (Target *target, - Module &module); + Module &module, + Stream* feedback_stream); virtual Error GetSharedModule (const ModuleSpec &module_spec, @@ -349,7 +355,7 @@ namespace lldb_private { /// A zero based architecture index /// /// @param[out] arch - /// A copy of the archgitecture at index if the return value is + /// A copy of the architecture at index if the return value is /// \b true. /// /// @return @@ -413,7 +419,7 @@ namespace lldb_private { /// attempt to attach to the process with the process ID of \a pid. /// The platform subclass should return an appropriate ProcessSP /// subclass that is attached to the process, or an empty shared - /// pointer with an appriopriate error. + /// pointer with an appropriate error. /// /// @param[in] pid /// The process ID that we should attempt to attach to. @@ -422,7 +428,7 @@ namespace lldb_private { /// An appropriate ProcessSP containing a valid shared pointer /// to the default Process subclass for the platform that is /// attached to the process, or an empty shared pointer with an - /// appriopriate error fill into the \a error object. + /// appropriate error fill into the \a error object. //------------------------------------------------------------------ virtual lldb::ProcessSP Attach (ProcessAttachInfo &attach_info, @@ -858,13 +864,72 @@ namespace lldb_private { virtual const std::vector & GetTrapHandlerSymbolNames (); + //------------------------------------------------------------------ + /// Launch a process for debugging. + /// + /// This differs from Launch in that it returns a NativeProcessProtocol. + /// Currently used by lldb-gdbserver. + /// + /// @param[in] launch_info + /// Information required to launch the process. + /// + /// @param[in] native_delegate + /// The delegate that will receive messages regarding the + /// inferior. Must outlive the NativeProcessProtocol + /// instance. + /// + /// @param[out] process_sp + /// On successful return from the method, this parameter + /// contains the shared pointer to the + /// NativeProcessProtocol that can be used to manipulate + /// the native process. + /// + /// @return + /// An error object indicating if the operation succeeded, + /// and if not, what error occurred. + //------------------------------------------------------------------ + virtual Error + LaunchNativeProcess ( + ProcessLaunchInfo &launch_info, + lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate, + NativeProcessProtocolSP &process_sp); + + //------------------------------------------------------------------ + /// Attach to an existing process on the given platform. + /// + /// This method differs from Attach() in that it returns a + /// NativeProcessProtocol. Currently this is used by lldb-gdbserver. + /// + /// @param[in] pid + /// pid of the process locatable by the platform. + /// + /// @param[in] native_delegate + /// The delegate that will receive messages regarding the + /// inferior. Must outlive the NativeProcessProtocol + /// instance. + /// + /// @param[out] process_sp + /// On successful return from the method, this parameter + /// contains the shared pointer to the + /// NativeProcessProtocol that can be used to manipulate + /// the native process. + /// + /// @return + /// An error object indicating if the operation succeeded, + /// and if not, what error occurred. + //------------------------------------------------------------------ + virtual Error + AttachNativeProcess (lldb::pid_t pid, + lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate, + NativeProcessProtocolSP &process_sp); + protected: bool m_is_host; // Set to true when we are able to actually set the OS version while // being connected. For remote platforms, we might set the version ahead // of time before we actually connect and this version might change when // we actually connect to a remote platform. For the host platform this - // will be set to the once we call Host::GetOSVersion(). + // will be set to the once we call HostInfo::GetOSVersion(). bool m_os_version_set_while_connected; bool m_system_arch_set_while_connected; ConstString m_sdk_sysroot; // the root location of where the SDK files are all located @@ -892,6 +957,7 @@ namespace lldb_private { std::string m_local_cache_directory; std::vector 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 diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h index b74347d37e68..641707c58deb 100644 --- a/include/lldb/Target/Process.h +++ b/include/lldb/Target/Process.h @@ -42,7 +42,11 @@ #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/Options.h" #include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Target/JITLoaderList.h" #include "lldb/Target/Memory.h" +#include "lldb/Target/MemoryRegionInfo.h" +#include "lldb/Target/ProcessInfo.h" +#include "lldb/Target/ProcessLaunchInfo.h" #include "lldb/Target/QueueList.h" #include "lldb/Target/ThreadList.h" #include "lldb/Target/UnixSignals.h" @@ -103,232 +107,6 @@ public: typedef std::shared_ptr ProcessPropertiesSP; -//---------------------------------------------------------------------- -// ProcessInfo -// -// A base class for information for a process. This can be used to fill -// out information for a process prior to launching it, or it can be -// used for an instance of a process and can be filled in with the -// existing values for that process. -//---------------------------------------------------------------------- -class ProcessInfo -{ -public: - ProcessInfo () : - m_executable (), - m_arguments (), - m_environment (), - m_uid (UINT32_MAX), - m_gid (UINT32_MAX), - m_arch(), - m_pid (LLDB_INVALID_PROCESS_ID) - { - } - - ProcessInfo (const char *name, - const ArchSpec &arch, - lldb::pid_t pid) : - m_executable (name, false), - m_arguments (), - m_environment(), - m_uid (UINT32_MAX), - m_gid (UINT32_MAX), - m_arch (arch), - m_pid (pid) - { - } - - void - Clear () - { - m_executable.Clear(); - m_arguments.Clear(); - m_environment.Clear(); - m_uid = UINT32_MAX; - m_gid = UINT32_MAX; - m_arch.Clear(); - m_pid = LLDB_INVALID_PROCESS_ID; - } - - const char * - GetName() const - { - return m_executable.GetFilename().GetCString(); - } - - size_t - GetNameLength() const - { - return m_executable.GetFilename().GetLength(); - } - - FileSpec & - GetExecutableFile () - { - return m_executable; - } - - void - SetExecutableFile (const FileSpec &exe_file, bool add_exe_file_as_first_arg) - { - if (exe_file) - { - m_executable = exe_file; - if (add_exe_file_as_first_arg) - { - char filename[PATH_MAX]; - if (exe_file.GetPath(filename, sizeof(filename))) - m_arguments.InsertArgumentAtIndex (0, filename); - } - } - else - { - m_executable.Clear(); - } - } - - const FileSpec & - GetExecutableFile () const - { - return m_executable; - } - - uint32_t - GetUserID() const - { - return m_uid; - } - - uint32_t - GetGroupID() const - { - return m_gid; - } - - bool - UserIDIsValid () const - { - return m_uid != UINT32_MAX; - } - - bool - GroupIDIsValid () const - { - return m_gid != UINT32_MAX; - } - - void - SetUserID (uint32_t uid) - { - m_uid = uid; - } - - void - SetGroupID (uint32_t gid) - { - m_gid = gid; - } - - ArchSpec & - GetArchitecture () - { - return m_arch; - } - - const ArchSpec & - GetArchitecture () const - { - return m_arch; - } - - void - SetArchitecture (ArchSpec arch) - { - m_arch = arch; - } - - lldb::pid_t - GetProcessID () const - { - return m_pid; - } - - void - SetProcessID (lldb::pid_t pid) - { - m_pid = pid; - } - - bool - ProcessIDIsValid() const - { - return m_pid != LLDB_INVALID_PROCESS_ID; - } - - void - Dump (Stream &s, Platform *platform) const; - - Args & - GetArguments () - { - return m_arguments; - } - - const Args & - GetArguments () const - { - return m_arguments; - } - - const char * - GetArg0 () const - { - if (m_arg0.empty()) - return NULL; - return m_arg0.c_str(); - } - - void - SetArg0 (const char *arg) - { - if (arg && arg[0]) - m_arg0 = arg; - else - m_arg0.clear(); - } - - void - SetArguments (const Args& args, bool first_arg_is_executable); - - void - SetArguments (char const **argv, bool first_arg_is_executable); - - Args & - GetEnvironmentEntries () - { - return m_environment; - } - - const Args & - GetEnvironmentEntries () const - { - return m_environment; - } - -protected: - FileSpec m_executable; - std::string m_arg0; // argv[0] if supported. If empty, then use m_executable. - // Not all process plug-ins support specifying an argv[0] - // that differs from the resolved platform executable - // (which is in m_executable) - Args m_arguments; // All program arguments except argv[0] - Args m_environment; - uint32_t m_uid; - uint32_t m_gid; - ArchSpec m_arch; - lldb::pid_t m_pid; -}; - //---------------------------------------------------------------------- // ProcessInstanceInfo // @@ -434,445 +212,10 @@ protected: lldb::pid_t m_parent_pid; }; - //---------------------------------------------------------------------- -// ProcessLaunchInfo +// ProcessAttachInfo // -// Describes any information that is required to launch a process. -//---------------------------------------------------------------------- - -class ProcessLaunchInfo : public ProcessInfo -{ -public: - - class FileAction - { - public: - enum Action - { - eFileActionNone, - eFileActionClose, - eFileActionDuplicate, - eFileActionOpen - }; - - - FileAction () : - m_action (eFileActionNone), - m_fd (-1), - m_arg (-1), - m_path () - { - } - - void - Clear() - { - m_action = eFileActionNone; - m_fd = -1; - m_arg = -1; - m_path.clear(); - } - - bool - Close (int fd); - - bool - Duplicate (int fd, int dup_fd); - - bool - Open (int fd, const char *path, bool read, bool write); - -#ifndef LLDB_DISABLE_POSIX - static bool - AddPosixSpawnFileAction (void *file_actions, - const FileAction *info, - Log *log, - Error& error); -#endif - - int - GetFD () const - { - return m_fd; - } - - Action - GetAction () const - { - return m_action; - } - - int - GetActionArgument () const - { - return m_arg; - } - - const char * - GetPath () const - { - if (m_path.empty()) - return NULL; - return m_path.c_str(); - } - - protected: - Action m_action; // The action for this file - int m_fd; // An existing file descriptor - int m_arg; // oflag for eFileActionOpen*, dup_fd for eFileActionDuplicate - std::string m_path; // A file path to use for opening after fork or posix_spawn - }; - - ProcessLaunchInfo () : - ProcessInfo(), - m_working_dir (), - m_plugin_name (), - m_shell (), - m_flags (0), - m_file_actions (), - m_pty (), - m_resume_count (0), - m_monitor_callback (NULL), - m_monitor_callback_baton (NULL), - m_monitor_signals (false), - m_hijack_listener_sp () - { - } - - ProcessLaunchInfo (const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - const char *working_directory, - uint32_t launch_flags) : - ProcessInfo(), - m_working_dir (), - m_plugin_name (), - m_shell (), - m_flags (launch_flags), - m_file_actions (), - m_pty (), - m_resume_count (0), - m_monitor_callback (NULL), - m_monitor_callback_baton (NULL), - m_monitor_signals (false), - m_hijack_listener_sp () - { - if (stdin_path) - { - ProcessLaunchInfo::FileAction file_action; - const bool read = true; - const bool write = false; - if (file_action.Open(STDIN_FILENO, stdin_path, read, write)) - AppendFileAction (file_action); - } - if (stdout_path) - { - ProcessLaunchInfo::FileAction file_action; - const bool read = false; - const bool write = true; - if (file_action.Open(STDOUT_FILENO, stdout_path, read, write)) - AppendFileAction (file_action); - } - if (stderr_path) - { - ProcessLaunchInfo::FileAction file_action; - const bool read = false; - const bool write = true; - if (file_action.Open(STDERR_FILENO, stderr_path, read, write)) - AppendFileAction (file_action); - } - if (working_directory) - SetWorkingDirectory(working_directory); - } - - void - AppendFileAction (const FileAction &info) - { - m_file_actions.push_back(info); - } - - bool - AppendCloseFileAction (int fd) - { - FileAction file_action; - if (file_action.Close (fd)) - { - AppendFileAction (file_action); - return true; - } - return false; - } - - bool - AppendDuplicateFileAction (int fd, int dup_fd) - { - FileAction file_action; - if (file_action.Duplicate (fd, dup_fd)) - { - AppendFileAction (file_action); - return true; - } - return false; - } - - bool - AppendOpenFileAction (int fd, const char *path, bool read, bool write) - { - FileAction file_action; - if (file_action.Open (fd, path, read, write)) - { - AppendFileAction (file_action); - return true; - } - return false; - } - - bool - AppendSuppressFileAction (int fd, bool read, bool write) - { - FileAction file_action; - if (file_action.Open (fd, "/dev/null", read, write)) - { - AppendFileAction (file_action); - return true; - } - return false; - } - - void - FinalizeFileActions (Target *target, - bool default_to_use_pty); - - size_t - GetNumFileActions () const - { - return m_file_actions.size(); - } - - const FileAction * - GetFileActionAtIndex (size_t idx) const - { - if (idx < m_file_actions.size()) - return &m_file_actions[idx]; - return NULL; - } - - const FileAction * - GetFileActionForFD (int fd) const - { - for (size_t idx=0, count=m_file_actions.size(); idx < count; ++idx) - { - if (m_file_actions[idx].GetFD () == fd) - return &m_file_actions[idx]; - } - return NULL; - } - - Flags & - GetFlags () - { - return m_flags; - } - - const Flags & - GetFlags () const - { - return m_flags; - } - - const char * - GetWorkingDirectory () const - { - if (m_working_dir.empty()) - return NULL; - return m_working_dir.c_str(); - } - - void - SetWorkingDirectory (const char *working_dir) - { - if (working_dir && working_dir[0]) - m_working_dir.assign (working_dir); - else - m_working_dir.clear(); - } - - void - SwapWorkingDirectory (std::string &working_dir) - { - m_working_dir.swap (working_dir); - } - - - const char * - GetProcessPluginName () const - { - if (m_plugin_name.empty()) - return NULL; - return m_plugin_name.c_str(); - } - - void - SetProcessPluginName (const char *plugin) - { - if (plugin && plugin[0]) - m_plugin_name.assign (plugin); - else - m_plugin_name.clear(); - } - - const char * - GetShell () const - { - if (m_shell.empty()) - return NULL; - return m_shell.c_str(); - } - - void - SetShell (const char * path) - { - if (path && path[0]) - { - m_shell.assign (path); - m_flags.Set (lldb::eLaunchFlagLaunchInShell); - } - else - { - m_shell.clear(); - m_flags.Clear (lldb::eLaunchFlagLaunchInShell); - } - } - - uint32_t - GetResumeCount () const - { - return m_resume_count; - } - - void - SetResumeCount (uint32_t c) - { - m_resume_count = c; - } - - bool - GetLaunchInSeparateProcessGroup () - { - return m_flags.Test(lldb::eLaunchFlagLaunchInSeparateProcessGroup); - } - - void - SetLaunchInSeparateProcessGroup (bool separate) - { - if (separate) - m_flags.Set(lldb::eLaunchFlagLaunchInSeparateProcessGroup); - else - m_flags.Clear (lldb::eLaunchFlagLaunchInSeparateProcessGroup); - - } - - void - Clear () - { - ProcessInfo::Clear(); - m_working_dir.clear(); - m_plugin_name.clear(); - m_shell.clear(); - m_flags.Clear(); - m_file_actions.clear(); - m_resume_count = 0; - m_hijack_listener_sp.reset(); - } - - bool - ConvertArgumentsForLaunchingInShell (Error &error, - bool localhost, - bool will_debug, - bool first_arg_is_full_shell_command, - int32_t num_resumes); - - void - SetMonitorProcessCallback (Host::MonitorChildProcessCallback callback, - void *baton, - bool monitor_signals) - { - m_monitor_callback = callback; - m_monitor_callback_baton = baton; - m_monitor_signals = monitor_signals; - } - - Host::MonitorChildProcessCallback - GetMonitorProcessCallback () - { - return m_monitor_callback; - } - - const void* - GetMonitorProcessBaton () const - { - return m_monitor_callback_baton; - } - - // If the LaunchInfo has a monitor callback, then arrange to monitor the process. - // Return true if the LaunchInfo has taken care of monitoring the process, and false if the - // caller might want to monitor the process themselves. - - bool - MonitorProcess () const - { - if (GetFlags().Test(lldb::eLaunchFlagsDontMonitorProcess)) - return true; - - if (m_monitor_callback && ProcessIDIsValid()) - { - Host::StartMonitoringChildProcess (m_monitor_callback, - m_monitor_callback_baton, - GetProcessID(), - m_monitor_signals); - return true; - } - return false; - } - - lldb_utility::PseudoTerminal & - GetPTY () - { - return m_pty; - } - - lldb::ListenerSP - GetHijackListener () const - { - return m_hijack_listener_sp; - } - - void - SetHijackListener (const lldb::ListenerSP &listener_sp) - { - m_hijack_listener_sp = listener_sp; - } - - -protected: - std::string m_working_dir; - std::string m_plugin_name; - std::string m_shell; - Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags - std::vector m_file_actions; // File actions for any other files - lldb_utility::PseudoTerminal m_pty; - uint32_t m_resume_count; // How many times do we resume after launching - Host::MonitorChildProcessCallback m_monitor_callback; - void *m_monitor_callback_baton; - bool m_monitor_signals; - lldb::ListenerSP m_hijack_listener_sp; -}; - -//---------------------------------------------------------------------- -// ProcessLaunchInfo -// -// Describes any information that is required to launch a process. +// Describes any information that is required to attach to a process. //---------------------------------------------------------------------- class ProcessAttachInfo : public ProcessInstanceInfo @@ -884,7 +227,8 @@ public: m_resume_count (0), m_wait_for_launch (false), m_ignore_existing (true), - m_continue_once_attached (false) + m_continue_once_attached (false), + m_detach_on_error (true) { } @@ -894,12 +238,14 @@ public: m_resume_count (0), m_wait_for_launch (false), m_ignore_existing (true), - m_continue_once_attached (false) + m_continue_once_attached (false), + m_detach_on_error(true) { ProcessInfo::operator= (launch_info); SetProcessPluginName (launch_info.GetProcessPluginName()); SetResumeCount (launch_info.GetResumeCount()); SetHijackListener(launch_info.GetHijackListener()); + m_detach_on_error = launch_info.GetDetachOnError(); } bool @@ -1002,7 +348,18 @@ public: m_hijack_listener_sp = listener_sp; } - + bool + GetDetachOnError () const + { + return m_detach_on_error; + } + + void + SetDetachOnError (bool enable) + { + m_detach_on_error = enable; + } + protected: lldb::ListenerSP m_hijack_listener_sp; std::string m_plugin_name; @@ -1010,6 +367,7 @@ protected: bool m_wait_for_launch; bool m_ignore_existing; bool m_continue_once_attached; // Supports the use-case scenario of immediately continuing the process once attached. + bool m_detach_on_error; // If we are debugging remotely, instruct the stub to detach rather than killing the target on error. }; class ProcessLaunchCommandOptions : public Options @@ -1034,6 +392,7 @@ public: OptionParsingStarting () { launch_info.Clear(); + disable_aslr = eLazyBoolCalculate; } const OptionDefinition* @@ -1049,6 +408,7 @@ public: // Instance variables to hold the values for command options. ProcessLaunchInfo launch_info; + lldb_private::LazyBool disable_aslr; }; //---------------------------------------------------------------------- @@ -1321,91 +681,6 @@ inline bool operator!= (const ProcessModID &lhs, const ProcessModID &rhs) return false; } -class MemoryRegionInfo -{ -public: - typedef Range RangeType; - - enum OptionalBool { - eDontKnow = -1, - eNo = 0, - eYes = 1 - }; - - MemoryRegionInfo () : - m_range (), - m_read (eDontKnow), - m_write (eDontKnow), - m_execute (eDontKnow) - { - } - - ~MemoryRegionInfo () - { - } - - RangeType & - GetRange() - { - return m_range; - } - - void - Clear() - { - m_range.Clear(); - m_read = m_write = m_execute = eDontKnow; - } - - const RangeType & - GetRange() const - { - return m_range; - } - - OptionalBool - GetReadable () const - { - return m_read; - } - - OptionalBool - GetWritable () const - { - return m_write; - } - - OptionalBool - GetExecutable () const - { - return m_execute; - } - - void - SetReadable (OptionalBool val) - { - m_read = val; - } - - void - SetWritable (OptionalBool val) - { - m_write = val; - } - - void - SetExecutable (OptionalBool val) - { - m_execute = val; - } - -protected: - RangeType m_range; - OptionalBool m_read; - OptionalBool m_write; - OptionalBool m_execute; -}; - //---------------------------------------------------------------------- /// @class Process Process.h "lldb/Target/Process.h" /// @brief A plug-in interface definition class for debugging a process. @@ -1418,7 +693,8 @@ class Process : public ExecutionContextScope, public PluginInterface { - friend class ClangFunction; // For WaitForStateChangeEventsPrivate + friend class ClangFunction; // For WaitForStateChangeEventsPrivate + friend class Debugger; // For PopProcessIOHandler and ProcessIOHandlerIsActive friend class ProcessEventData; friend class StopInfo; friend class Target; @@ -1619,9 +895,16 @@ public: //------------------------------------------------------------------ /// Construct with a shared pointer to a target, and the Process listener. + /// Uses the Host UnixSignalsSP by default. //------------------------------------------------------------------ Process(Target &target, Listener &listener); + //------------------------------------------------------------------ + /// Construct with a shared pointer to a target, the Process listener, + /// and the appropriate UnixSignalsSP for the process. + //------------------------------------------------------------------ + Process(Target &target, Listener &listener, const UnixSignalsSP &unix_signals_sp); + //------------------------------------------------------------------ /// Destructor. /// @@ -1753,10 +1036,6 @@ public: /// /// Launch a new process by spawning a new process using the /// target object's executable module's file as the file to launch. - /// Arguments are given in \a argv, and the environment variables - /// are in \a envp. Standard input and output files can be - /// optionally re-directed to \a stdin_path, \a stdout_path, and - /// \a stderr_path. /// /// This function is not meant to be overridden by Process /// subclasses. It will first call Process::WillLaunch (Module *) @@ -1766,32 +1045,9 @@ public: /// DoLaunch returns \b true, then Process::DidLaunch() will be /// called. /// - /// @param[in] argv - /// The argument array. - /// - /// @param[in] envp - /// The environment array. - /// - /// @param[in] launch_flags - /// Flags to modify the launch (@see lldb::LaunchFlags) - /// - /// @param[in] stdin_path - /// The path to use when re-directing the STDIN of the new - /// process. If all stdXX_path arguments are NULL, a pseudo - /// terminal will be used. - /// - /// @param[in] stdout_path - /// The path to use when re-directing the STDOUT of the new - /// process. If all stdXX_path arguments are NULL, a pseudo - /// terminal will be used. - /// - /// @param[in] stderr_path - /// The path to use when re-directing the STDERR of the new - /// process. If all stdXX_path arguments are NULL, a pseudo - /// terminal will be used. - /// - /// @param[in] working_directory - /// The working directory to have the child process run in + /// @param[in] launch_info + /// Details regarding the environment, STDIN/STDOUT/STDERR + /// redirection, working path, etc. related to the requested launch. /// /// @return /// An error object. Call GetID() to get the process ID if @@ -1823,6 +1079,22 @@ public: virtual DynamicLoader * GetDynamicLoader (); + //------------------------------------------------------------------ + // Returns AUXV structure found in many ELF-based environments. + // + // The default action is to return an empty data buffer. + // + // @return + // A data buffer containing the contents of the AUXV data. + //------------------------------------------------------------------ + virtual const lldb::DataBufferSP + GetAuxvData(); + +protected: + virtual JITLoaderList & + GetJITLoaders (); + +public: //------------------------------------------------------------------ /// Get the system runtime plug-in for this process. /// @@ -1930,7 +1202,7 @@ public: //------------------------------------------------------------------ /// Register for process and thread notifications. /// - /// Clients can register nofication callbacks by filling out a + /// Clients can register notification callbacks by filling out a /// Process::Notifications structure and calling this function. /// /// @param[in] callbacks @@ -1946,7 +1218,7 @@ public: //------------------------------------------------------------------ /// Unregister for process and thread notifications. /// - /// Clients can unregister nofication callbacks by passing a copy of + /// Clients can unregister notification callbacks by passing a copy of /// the original baton and callbacks in \a callbacks. /// /// @param[in] callbacks @@ -2056,10 +1328,18 @@ public: Error Signal (int signal); - virtual UnixSignals & + void + SetUnixSignals (const UnixSignalsSP &signals_sp) + { + assert (signals_sp && "null signals_sp"); + m_unix_signals_sp = signals_sp; + } + + UnixSignals & GetUnixSignals () { - return m_unix_signals; + assert (m_unix_signals_sp && "null m_unix_signals_sp"); + return *m_unix_signals_sp; } //================================================================== @@ -2183,11 +1463,17 @@ public: //------------------------------------------------------------------ /// Called after attaching a process. /// + /// @param[in] process_arch + /// If you can figure out the process architecture after attach, fill it in here. + /// /// Allow Process plug-ins to execute some code after attaching to /// a process. //------------------------------------------------------------------ virtual void - DidAttach () {} + DidAttach (ArchSpec &process_arch) + { + process_arch.Clear(); + } //------------------------------------------------------------------ @@ -2229,46 +1515,21 @@ public: //------------------------------------------------------------------ /// Launch a new process. /// - /// Launch a new process by spawning a new process using \a module's - /// file as the file to launch. Arguments are given in \a argv, - /// and the environment variables are in \a envp. Standard input - /// and output files can be optionally re-directed to \a stdin_path, - /// \a stdout_path, and \a stderr_path. + /// Launch a new process by spawning a new process using + /// \a exe_module's file as the file to launch. Launch details are + /// provided in \a launch_info. /// - /// @param[in] module + /// @param[in] exe_module /// The module from which to extract the file specification and /// launch. /// - /// @param[in] argv - /// The argument array. - /// - /// @param[in] envp - /// The environment array. - /// - /// @param[in] launch_flags - /// Flags to modify the launch (@see lldb::LaunchFlags) - /// - /// @param[in] stdin_path - /// The path to use when re-directing the STDIN of the new - /// process. If all stdXX_path arguments are NULL, a pseudo - /// terminal will be used. - /// - /// @param[in] stdout_path - /// The path to use when re-directing the STDOUT of the new - /// process. If all stdXX_path arguments are NULL, a pseudo - /// terminal will be used. - /// - /// @param[in] stderr_path - /// The path to use when re-directing the STDERR of the new - /// process. If all stdXX_path arguments are NULL, a pseudo - /// terminal will be used. - /// - /// @param[in] working_directory - /// The working directory to have the child process run in + /// @param[in] launch_info + /// Details (e.g. arguments, stdio redirection, etc.) for the + /// requested launch. /// /// @return - /// A new valid process ID, or LLDB_INVALID_PROCESS_ID if - /// launching fails. + /// An Error instance indicating success or failure of the + /// operation. //------------------------------------------------------------------ virtual Error DoLaunch (Module *exe_module, @@ -2454,7 +1715,7 @@ public: DoSignal (int signal) { Error error; - error.SetErrorStringWithFormat("error: %s does not support senging signals to processes", GetPluginName().GetCString()); + error.SetErrorStringWithFormat("error: %s does not support sending signals to processes", GetPluginName().GetCString()); return error; } @@ -2546,14 +1807,14 @@ public: lldb::StateType GetState (); - ExecutionResults + lldb::ExpressionResults RunThreadPlan (ExecutionContext &exe_ctx, lldb::ThreadPlanSP &thread_plan_sp, const EvaluateExpressionOptions &options, Stream &errors); static const char * - ExecutionResultAsCString (ExecutionResults result); + ExecutionResultAsCString (lldb::ExpressionResults result); void GetStatus (Stream &ostrm); @@ -2568,6 +1829,9 @@ public: void SendAsyncInterrupt (); + void + ModulesDidLoad (ModuleList &module_list); + protected: void @@ -2904,7 +2168,7 @@ public: /// /// The value contained in \a scalar will be swapped to match the /// byte order of the process that is being debugged. If \a size is - /// less than the size of scalar, the least significate \a size bytes + /// less than the size of scalar, the least significant \a size bytes /// from scalar will be written. If \a size is larger than the byte /// size of scalar, then the extra space will be padded with zeros /// and the scalar value will be placed in the least significant @@ -3070,7 +2334,8 @@ public: lldb::ModuleSP ReadModuleFromMemory (const FileSpec& file_spec, - lldb::addr_t header_addr); + lldb::addr_t header_addr, + size_t size_to_read = 512); //------------------------------------------------------------------ /// Attempt to get the attributes for a region of memory in the process. @@ -3412,6 +2677,25 @@ public: bool wait_always = true, Listener *hijack_listener = NULL); + + //-------------------------------------------------------------------------------------- + /// Waits for the process state to be running within a given msec timeout. + /// + /// The main purpose of this is to implement an interlock waiting for HandlePrivateEvent + /// to push an IOHandler. + /// + /// @param[in] timeout_msec + /// The maximum time length to wait for the process to transition to the + /// eStateRunning state, specified in milliseconds. + /// + /// @return + /// true if successfully signalled that process started and IOHandler pushes, false + /// if it timed out. + //-------------------------------------------------------------------------------------- + bool + SyncIOHandler (uint64_t timeout_msec); + + lldb::StateType WaitForStateChangedEvents (const TimeValue *timeout, lldb::EventSP &event_sp, @@ -3582,12 +2866,6 @@ public: void SetSTDIOFileDescriptor (int file_descriptor); - void - WatchForSTDIN (IOHandler &io_handler); - - void - CancelWatchForSTDIN (bool exited); - //------------------------------------------------------------------ // Add a permanent region of memory that should never be read or // written to. This can be used to ensure that memory reads or writes @@ -3633,8 +2911,17 @@ public: else return m_public_run_lock; } - + +public: + virtual Error + SendEventData(const char *data) + { + Error return_error ("Sending an event is not supported for this process."); + return return_error; + } + protected: + //------------------------------------------------------------------ // NextEventAction provides a way to register an action on the next // event that is delivered to this process. There is currently only @@ -3690,13 +2977,9 @@ protected: class AttachCompletionHandler : public NextEventAction { public: - AttachCompletionHandler (Process *process, uint32_t exec_count) : - NextEventAction (process), - m_exec_count (exec_count) - { - } + AttachCompletionHandler (Process *process, uint32_t exec_count); - virtual + virtual ~AttachCompletionHandler() { } @@ -3753,7 +3036,7 @@ protected: Broadcaster m_private_state_control_broadcaster; // This is the control broadcaster, used to pause, resume & stop the private state thread. Listener m_private_state_listener; // This is the listener for the private state thread. Predicate m_private_state_control_wait; /// This Predicate is used to signal that a control operation is complete. - lldb::thread_t m_private_state_thread; // Thread ID for the thread that watches interal state events + lldb::thread_t m_private_state_thread; // Thread ID for the thread that watches internal state events ProcessModID m_mod_id; ///< Tracks the state of the process over stops and other alterations. uint32_t m_process_unique_id; ///< Each lldb_private::Process class that is created gets a unique integer ID that increments with each new instance uint32_t m_thread_index_id; ///< Each thread is created with a 1 based index that won't get re-used. @@ -3773,10 +3056,11 @@ protected: Listener &m_listener; BreakpointSiteList m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend to insert in the target. std::unique_ptr m_dyld_ap; + std::unique_ptr m_jit_loaders_ap; std::unique_ptr m_dynamic_checkers_ap; ///< The functions used by the expression parser to validate data that expressions use. std::unique_ptr m_os_ap; std::unique_ptr m_system_runtime_ap; - UnixSignals m_unix_signals; /// This is the current signal set for this process. + UnixSignalsSP m_unix_signals_sp; /// This is the current signal set for this process. lldb::ABISP m_abi_sp; lldb::IOHandlerSP m_process_input_reader; Communication m_stdio_communication; @@ -3785,6 +3069,7 @@ protected: std::string m_stderr_data; Mutex m_profile_data_comm_mutex; std::vector m_profile_data; + Predicate m_iohandler_sync; MemoryCache m_memory_cache; AllocatedMemoryCache m_allocated_memory_cache; bool m_should_detach; /// Should we detach if the process object goes away with an explicit call to Kill or Detach? @@ -3874,15 +3159,15 @@ protected: static void STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len); - void + bool PushProcessIOHandler (); - void + bool PopProcessIOHandler (); - void - ResetProcessIOHandler (); - + bool + ProcessIOHandlerIsActive (); + Error HaltForDestroyOrDetach(lldb::EventSP &exit_event_sp); diff --git a/include/lldb/Target/ProcessInfo.h b/include/lldb/Target/ProcessInfo.h new file mode 100644 index 000000000000..0570cfc98651 --- /dev/null +++ b/include/lldb/Target/ProcessInfo.h @@ -0,0 +1,188 @@ +//===-- ProcessInfo.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_ProcessInfo_h_ +#define liblldb_ProcessInfo_h_ + +// LLDB headers +#include "lldb/Core/ArchSpec.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Interpreter/Args.h" + +namespace lldb_private +{ + //---------------------------------------------------------------------- + // ProcessInfo + // + // A base class for information for a process. This can be used to fill + // out information for a process prior to launching it, or it can be + // used for an instance of a process and can be filled in with the + // existing values for that process. + //---------------------------------------------------------------------- + class ProcessInfo + { + public: + ProcessInfo (); + + ProcessInfo (const char *name, + const ArchSpec &arch, + lldb::pid_t pid); + + void + Clear (); + + const char * + GetName() const; + + size_t + GetNameLength() const; + + FileSpec & + GetExecutableFile () + { + return m_executable; + } + + void + SetExecutableFile (const FileSpec &exe_file, bool add_exe_file_as_first_arg); + + const FileSpec & + GetExecutableFile () const + { + return m_executable; + } + + uint32_t + GetUserID() const + { + return m_uid; + } + + uint32_t + GetGroupID() const + { + return m_gid; + } + + bool + UserIDIsValid () const + { + return m_uid != UINT32_MAX; + } + + bool + GroupIDIsValid () const + { + return m_gid != UINT32_MAX; + } + + void + SetUserID (uint32_t uid) + { + m_uid = uid; + } + + void + SetGroupID (uint32_t gid) + { + m_gid = gid; + } + + ArchSpec & + GetArchitecture () + { + return m_arch; + } + + const ArchSpec & + GetArchitecture () const + { + return m_arch; + } + + void + SetArchitecture (ArchSpec arch) + { + m_arch = arch; + } + + lldb::pid_t + GetProcessID () const + { + return m_pid; + } + + void + SetProcessID (lldb::pid_t pid) + { + m_pid = pid; + } + + bool + ProcessIDIsValid() const + { + return m_pid != LLDB_INVALID_PROCESS_ID; + } + + void + Dump (Stream &s, Platform *platform) const; + + Args & + GetArguments () + { + return m_arguments; + } + + const Args & + GetArguments () const + { + return m_arguments; + } + + const char * + GetArg0 () const; + + void + SetArg0 (const char *arg); + + void + SetArguments (const Args& args, bool first_arg_is_executable); + + void + SetArguments (char const **argv, bool first_arg_is_executable); + + Args & + GetEnvironmentEntries () + { + return m_environment; + } + + const Args & + GetEnvironmentEntries () const + { + return m_environment; + } + + protected: + FileSpec m_executable; + std::string m_arg0; // argv[0] if supported. If empty, then use m_executable. + // Not all process plug-ins support specifying an argv[0] + // that differs from the resolved platform executable + // (which is in m_executable) + Args m_arguments; // All program arguments except argv[0] + Args m_environment; + uint32_t m_uid; + uint32_t m_gid; + ArchSpec m_arch; + lldb::pid_t m_pid; + }; +} + +#endif // #ifndef liblldb_ProcessInfo_h_ + diff --git a/include/lldb/Target/ProcessLaunchInfo.h b/include/lldb/Target/ProcessLaunchInfo.h new file mode 100644 index 000000000000..77d829a7e476 --- /dev/null +++ b/include/lldb/Target/ProcessLaunchInfo.h @@ -0,0 +1,225 @@ +//===-- ProcessLaunchInfo.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_ProcessLaunch_Info_h +#define liblldb_ProcessLaunch_Info_h + +// C++ Headers +#include + +// LLDB Headers +#include "lldb/Core/Flags.h" +#include "lldb/Host/Host.h" +#include "lldb/Target/FileAction.h" +#include "lldb/Target/ProcessInfo.h" +#include "lldb/Utility/PseudoTerminal.h" + +namespace lldb_private +{ + + //---------------------------------------------------------------------- + // ProcessLaunchInfo + // + // Describes any information that is required to launch a process. + //---------------------------------------------------------------------- + + class ProcessLaunchInfo : public ProcessInfo + { + public: + + ProcessLaunchInfo (); + + ProcessLaunchInfo (const char *stdin_path, + const char *stdout_path, + const char *stderr_path, + const char *working_directory, + uint32_t launch_flags); + + void + AppendFileAction (const FileAction &info) + { + m_file_actions.push_back(info); + } + + bool + AppendCloseFileAction (int fd); + + bool + AppendDuplicateFileAction (int fd, int dup_fd); + + bool + AppendOpenFileAction (int fd, const char *path, bool read, bool write); + + bool + AppendSuppressFileAction (int fd, bool read, bool write); + + void + FinalizeFileActions (Target *target, + bool default_to_use_pty); + + size_t + GetNumFileActions () const + { + return m_file_actions.size(); + } + + const FileAction * + GetFileActionAtIndex (size_t idx) const; + + const FileAction * + GetFileActionForFD (int fd) const; + + Flags & + GetFlags () + { + return m_flags; + } + + const Flags & + GetFlags () const + { + return m_flags; + } + + const char * + GetWorkingDirectory () const; + + void + SetWorkingDirectory (const char *working_dir); + + void + SwapWorkingDirectory (std::string &working_dir) + { + m_working_dir.swap (working_dir); + } + + const char * + GetProcessPluginName () const; + + void + SetProcessPluginName (const char *plugin); + + const char * + GetShell () const; + + void + SetShell (const char * path); + + uint32_t + GetResumeCount () const + { + return m_resume_count; + } + + void + SetResumeCount (uint32_t c) + { + m_resume_count = c; + } + + bool + GetLaunchInSeparateProcessGroup () + { + return m_flags.Test(lldb::eLaunchFlagLaunchInSeparateProcessGroup); + } + + void + SetLaunchInSeparateProcessGroup (bool separate); + + void + Clear (); + + bool + ConvertArgumentsForLaunchingInShell (Error &error, + bool localhost, + bool will_debug, + bool first_arg_is_full_shell_command, + int32_t num_resumes); + + void + SetMonitorProcessCallback (Host::MonitorChildProcessCallback callback, + void *baton, + bool monitor_signals); + + Host::MonitorChildProcessCallback + GetMonitorProcessCallback () + { + return m_monitor_callback; + } + + const void* + GetMonitorProcessBaton () const + { + return m_monitor_callback_baton; + } + + // If the LaunchInfo has a monitor callback, then arrange to monitor the process. + // Return true if the LaunchInfo has taken care of monitoring the process, and false if the + // caller might want to monitor the process themselves. + + bool + MonitorProcess () const; + + lldb_utility::PseudoTerminal & + GetPTY () + { + return m_pty; + } + + lldb::ListenerSP + GetHijackListener () const + { + return m_hijack_listener_sp; + } + + void + SetHijackListener (const lldb::ListenerSP &listener_sp) + { + m_hijack_listener_sp = listener_sp; + } + + + void + SetLaunchEventData (const char *data) + { + m_event_data.assign (data); + } + + const char * + GetLaunchEventData () const + { + return m_event_data.c_str(); + } + + void + SetDetachOnError (bool enable); + + bool + GetDetachOnError () const + { + return m_flags.Test(lldb::eLaunchFlagDetachOnError); + } + + protected: + std::string m_working_dir; + std::string m_plugin_name; + std::string m_shell; + Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags + std::vector m_file_actions; // File actions for any other files + lldb_utility::PseudoTerminal m_pty; + uint32_t m_resume_count; // How many times do we resume after launching + Host::MonitorChildProcessCallback m_monitor_callback; + void *m_monitor_callback_baton; + bool m_monitor_signals; + std::string m_event_data; // A string passed to the plugin launch, having no meaning to the upper levels of lldb. + lldb::ListenerSP m_hijack_listener_sp; + }; +} + +#endif // liblldb_ProcessLaunch_Info_h diff --git a/include/lldb/Target/Queue.h b/include/lldb/Target/Queue.h index 32ee24aebc11..514481fe8c9d 100644 --- a/include/lldb/Target/Queue.h +++ b/include/lldb/Target/Queue.h @@ -168,6 +168,18 @@ public: m_pending_items.push_back (item); } + //------------------------------------------------------------------ + /// Return the kind (serial, concurrent) of this queue + /// + /// @return + // Whether this is a serial or a concurrent queue + //------------------------------------------------------------------ + lldb::QueueKind + GetKind (); + + void + SetKind (lldb::QueueKind kind); + private: //------------------------------------------------------------------ // For Queue only @@ -180,6 +192,7 @@ private: uint32_t m_pending_work_items_count; std::vector m_pending_items; lldb::addr_t m_dispatch_queue_t_addr; // address of libdispatch dispatch_queue_t for this Queue + lldb::QueueKind m_kind; DISALLOW_COPY_AND_ASSIGN (Queue); }; diff --git a/include/lldb/Target/QueueItem.h b/include/lldb/Target/QueueItem.h index 76270da3bee6..c69c825a7976 100644 --- a/include/lldb/Target/QueueItem.h +++ b/include/lldb/Target/QueueItem.h @@ -14,6 +14,7 @@ #include "lldb/lldb-private.h" #include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" #include "lldb/Core/Address.h" #include "lldb/Core/ConstString.h" @@ -37,7 +38,7 @@ class QueueItem : { public: - QueueItem (lldb::QueueSP queue_sp); + QueueItem (lldb::QueueSP queue_sp, lldb::ProcessSP process_sp, lldb::addr_t item_ref, lldb_private::Address address); ~QueueItem (); @@ -49,7 +50,7 @@ public: /// represents. eQueueItemKindUnknown may be returned. //------------------------------------------------------------------ lldb::QueueItemKind - GetKind () const; + GetKind (); //------------------------------------------------------------------ /// Set the type of work item this is @@ -124,10 +125,7 @@ public: } lldb::addr_t - GetItemThatEnqueuedThis () - { - return m_item_that_enqueued_this_ref; - } + GetItemThatEnqueuedThis (); void SetEnqueueingThreadID (lldb::tid_t tid) @@ -136,10 +134,7 @@ public: } lldb::tid_t - GetEnqueueingThreadID () - { - return m_enqueueing_thread_id; - } + GetEnqueueingThreadID (); void SetEnqueueingQueueID (lldb::queue_id_t qid) @@ -148,10 +143,7 @@ public: } lldb::queue_id_t - GetEnqueueingQueueID () - { - return m_enqueueing_queue_id; - } + GetEnqueueingQueueID (); void SetTargetQueueID (lldb::queue_id_t qid) @@ -166,10 +158,7 @@ public: } uint32_t - GetStopID () - { - return m_stop_id; - } + GetStopID (); void SetEnqueueingBacktrace (std::vector backtrace) @@ -178,10 +167,7 @@ public: } std::vector & - GetEnqueueingBacktrace () - { - return m_backtrace; - } + GetEnqueueingBacktrace (); void SetThreadLabel (std::string thread_name) @@ -190,10 +176,7 @@ public: } std::string - GetThreadLabel () - { - return m_thread_label; - } + GetThreadLabel (); void SetQueueLabel (std::string queue_name) @@ -202,10 +185,7 @@ public: } std::string - GetQueueLabel () - { - return m_queue_label; - } + GetQueueLabel (); void SetTargetQueueLabel (std::string queue_name) @@ -213,11 +193,22 @@ public: m_target_queue_label = queue_name; } + lldb::ProcessSP + GetProcessSP (); + protected: + void + FetchEntireItem (); + + lldb::QueueWP m_queue_wp; - lldb::QueueItemKind m_kind; + lldb::ProcessWP m_process_wp; + + lldb::addr_t m_item_ref; // the token we can be used to fetch more information about this queue item lldb_private::Address m_address; + bool m_have_fetched_entire_item; + lldb::QueueItemKind m_kind; lldb::addr_t m_item_that_enqueued_this_ref; // a handle that we can pass into libBacktraceRecording // to get the QueueItem that enqueued this item lldb::tid_t m_enqueueing_thread_id; // thread that enqueued this item diff --git a/include/lldb/Target/QueueList.h b/include/lldb/Target/QueueList.h index 964c1099233e..12a0ea52d7f4 100644 --- a/include/lldb/Target/QueueList.h +++ b/include/lldb/Target/QueueList.h @@ -98,7 +98,7 @@ public: /// /// @return /// A QueueSP to the queue requested, if it is present in the QueueList. - /// An empty QueueSP willbe returned if this queue was not found. + /// An empty QueueSP will be returned if this queue was not found. //------------------------------------------------------------------ lldb::QueueSP FindQueueByID (lldb::queue_id_t qid); @@ -114,7 +114,7 @@ public: /// /// @return /// A QueueSP to the queue requested, if it is present in the QueueList. - /// An empty QueueSP willbe returned if this queue was not found. + /// An empty QueueSP will be returned if this queue was not found. //------------------------------------------------------------------ lldb::QueueSP FindQueueByIndexID (uint32_t index_id); diff --git a/include/lldb/Target/RegisterContext.h b/include/lldb/Target/RegisterContext.h index 421acc03cb22..9108d4575259 100644 --- a/include/lldb/Target/RegisterContext.h +++ b/include/lldb/Target/RegisterContext.h @@ -86,9 +86,44 @@ public: bool CopyFromRegisterContext (lldb::RegisterContextSP context); - + + //------------------------------------------------------------------ + /// Convert from a given register numbering scheme to the lldb register + /// numbering scheme + /// + /// There may be multiple ways to enumerate the registers for a given + /// architecture. ABI references will specify one to be used with + /// DWARF, the register numberings from stabs (aka "gcc"), there may + /// be a variation used for eh_frame unwind instructions (e.g. on Darwin), + /// and so on. Register 5 by itself is meaningless - RegisterKind + /// enumeration tells you what context that number should be translated as. + /// + /// Inside lldb, register numbers are in the eRegisterKindLLDB scheme; + /// arguments which take a register number should take one in that + /// scheme. + /// + /// eRegisterKindGeneric is a special numbering scheme which gives us + /// constant values for the pc, frame register, stack register, etc., for + /// use within lldb. They may not be defined for all architectures but + /// it allows generic code to translate these common registers into the + /// lldb numbering scheme. + /// + /// This method translates a given register kind + register number into + /// the eRegisterKindLLDB register numbering. + /// + /// @param [in] kind + /// The register numbering scheme (RegisterKind) that the following + /// register number is in. + /// + /// @param [in] num + /// A register number in the 'kind' register numbering scheme. + /// + /// @return + /// The equivalent register number in the eRegisterKindLLDB + /// numbering scheme, if possible, else LLDB_INVALID_REGNUM. + //------------------------------------------------------------------ virtual uint32_t - ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) = 0; + ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num) = 0; //------------------------------------------------------------------ // Subclasses can override these functions if desired @@ -136,7 +171,7 @@ public: GetRegisterInfoByName (const char *reg_name, uint32_t start_idx = 0); const RegisterInfo * - GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num); + GetRegisterInfo (lldb::RegisterKind reg_kind, uint32_t reg_num); uint64_t GetPC (uint64_t fail_value = LLDB_INVALID_ADDRESS); @@ -179,7 +214,7 @@ public: bool WriteRegisterFromUnsigned (const RegisterInfo *reg_info, uint64_t uval); bool - ConvertBetweenRegisterKinds (int source_rk, uint32_t source_regnum, int target_rk, uint32_t& target_regnum); + ConvertBetweenRegisterKinds (lldb::RegisterKind source_rk, uint32_t source_regnum, lldb::RegisterKind target_rk, uint32_t& target_regnum); //------------------------------------------------------------------ // lldb::ExecutionContextScope pure virtual functions diff --git a/include/lldb/Target/StackFrame.h b/include/lldb/Target/StackFrame.h index e7b57cd26ac9..1274dcc64bd3 100644 --- a/include/lldb/Target/StackFrame.h +++ b/include/lldb/Target/StackFrame.h @@ -177,7 +177,7 @@ public: /// /// The StackFrame maintains this SymbolContext and adds additional information /// to it on an as-needed basis. This helps to avoid different functions - /// looking up symbolic information for a given pc value multple times. + /// looking up symbolic information for a given pc value multiple times. /// /// @params [in] resolve_scope /// Flags from the SymbolContextItem enumerated type which specify what @@ -261,7 +261,7 @@ public: /// /// @param[in] get_file_globals /// Whether to also retrieve compilation-unit scoped variables - /// that are visisble to the entire compilation unit (e.g. file + /// that are visible to the entire compilation unit (e.g. file /// static in C, globals that are homed in this CU). /// /// @return @@ -279,7 +279,7 @@ public: /// /// @param[in] get_file_globals /// Whether to also retrieve compilation-unit scoped variables - /// that are visisble to the entire compilation unit (e.g. file + /// that are visible to the entire compilation unit (e.g. file /// static in C, globals that are homed in this CU). /// /// @return diff --git a/include/lldb/Target/StopInfo.h b/include/lldb/Target/StopInfo.h index 3435d392e2b9..8de40e852f4c 100644 --- a/include/lldb/Target/StopInfo.h +++ b/include/lldb/Target/StopInfo.h @@ -157,7 +157,9 @@ public: CreateStopReasonToTrace (Thread &thread); static lldb::StopInfoSP - CreateStopReasonWithPlan (lldb::ThreadPlanSP &plan, lldb::ValueObjectSP return_valobj_sp); + CreateStopReasonWithPlan (lldb::ThreadPlanSP &plan, + lldb::ValueObjectSP return_valobj_sp, + lldb::ClangExpressionVariableSP expression_variable_sp); static lldb::StopInfoSP CreateStopReasonWithException (Thread &thread, const char *description); @@ -168,6 +170,9 @@ public: static lldb::ValueObjectSP GetReturnValueObject (lldb::StopInfoSP &stop_info_sp); + static lldb::ClangExpressionVariableSP + GetExpressionVariable (lldb::StopInfoSP &stop_info_sp); + protected: // Perform any action that is associated with this stop. This is done as the // Event is removed from the event queue. ProcessEventData::DoOnRemoval does the job. diff --git a/include/lldb/Target/SystemRuntime.h b/include/lldb/Target/SystemRuntime.h index 363ce122c4f3..18f38f79bdbd 100644 --- a/include/lldb/Target/SystemRuntime.h +++ b/include/lldb/Target/SystemRuntime.h @@ -20,6 +20,7 @@ #include "lldb/Core/ConstString.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/PluginInterface.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Target/QueueList.h" #include "lldb/Target/QueueItem.h" #include "lldb/lldb-private.h" @@ -222,7 +223,7 @@ public: /// get the queue name and return it. /// /// @param [in] dispatch_qaddr - /// The address of the dispatch_queue_t structure for this thread. + /// The address of the dispatch_qaddr pointer for this thread. /// /// @return /// The string of this queue's name. An empty string is returned if the @@ -244,7 +245,7 @@ public: /// get the queue ID and return it. /// /// @param [in] dispatch_qaddr - /// The address of the dispatch_queue_t structure for this thread. + /// The address of the dispatch_qaddr pointer for this thread. /// /// @return /// The queue ID, or if it could not be retrieved, LLDB_INVALID_QUEUE_ID. @@ -255,6 +256,26 @@ public: return LLDB_INVALID_QUEUE_ID; } + //------------------------------------------------------------------ + /// Get the libdispatch_queue_t address for the queue given the thread's dispatch_qaddr. + /// + /// On systems using libdispatch queues, a thread may be associated with a queue. + /// There will be a call to get the thread's dispatch_qaddr. + /// Given the thread's dispatch_qaddr, find the libdispatch_queue_t address and + /// return it. + /// + /// @param [in] dispatch_qaddr + /// The address of the dispatch_qaddr pointer for this thread. + /// + /// @return + /// The libdispatch_queue_t address, or LLDB_INVALID_ADDRESS if unavailable/not found. + //------------------------------------------------------------------ + virtual lldb::addr_t + GetLibdispatchQueueAddressFromThreadQAddress (lldb::addr_t dispatch_qaddr) + { + return LLDB_INVALID_ADDRESS; + } + //------------------------------------------------------------------ /// Get the pending work items for a libdispatch Queue /// @@ -270,6 +291,60 @@ public: { } + //------------------------------------------------------------------ + /// Complete the fields in a QueueItem + /// + /// PopulatePendingItemsForQueue() may not fill in all of the QueueItem + /// details; when the remaining fields are needed, they will be + /// fetched by call this method. + /// + /// @param [in] queue_item + /// The QueueItem that we will be completing. + /// + /// @param [in] item_ref + /// The item_ref token that is needed to retrieve the rest of the + /// information about the QueueItem. + //------------------------------------------------------------------ + virtual void + CompleteQueueItem (lldb_private::QueueItem *queue_item, lldb::addr_t item_ref) + { + } + + //------------------------------------------------------------------ + /// Add key-value pairs to the StructuredData dictionary object with + /// information debugserver may need when constructing the jThreadExtendedInfo + /// packet. + /// + /// @param [out] dict + /// Dictionary to which key-value pairs should be added; they will + /// be sent to the remote gdb server stub as arguments in the + /// jThreadExtendedInfo request. + //------------------------------------------------------------------ + virtual void + AddThreadExtendedInfoPacketHints (lldb_private::StructuredData::ObjectSP dict) + { + } + + /// Determine whether it is safe to run an expression on a given thread + /// + /// If a system must not run functions on a thread in some particular state, + /// this method gives a way for it to flag that the expression should not be + /// run. + /// + /// @param [in] thread_sp + /// The thread we want to run the expression on. + /// + /// @return + /// True will be returned if there are no known problems with running an + /// expression on this thread. False means that the inferior function + /// call should not be made on this thread. + //------------------------------------------------------------------ + virtual bool + SafeToCallFunctionsOnThisThread (lldb::ThreadSP thread_sp) + { + return true; + } + protected: //------------------------------------------------------------------ // Member variables. diff --git a/include/lldb/Target/Target.h b/include/lldb/Target/Target.h index e65a511ab77a..64f3edf0fc4f 100644 --- a/include/lldb/Target/Target.h +++ b/include/lldb/Target/Target.h @@ -81,6 +81,12 @@ public: void SetDisableASLR (bool b); + bool + GetDetachOnError () const; + + void + SetDetachOnError (bool b); + bool GetDisableSTDIO () const; @@ -201,9 +207,15 @@ public: m_stop_others(true), m_debug(false), m_trap_exceptions(true), + m_generate_debug_info(false), + m_result_is_internal(false), m_use_dynamic(lldb::eNoDynamicValues), - m_timeout_usec(default_timeout) - {} + m_timeout_usec(default_timeout), + m_one_thread_timeout_usec(0), + m_cancel_callback (nullptr), + m_cancel_callback_baton (nullptr) + { + } ExecutionPolicy GetExecutionPolicy () const @@ -301,6 +313,18 @@ public: m_timeout_usec = timeout; } + uint32_t + GetOneThreadTimeoutUsec () const + { + return m_one_thread_timeout_usec; + } + + void + SetOneThreadTimeoutUsec (uint32_t timeout = 0) + { + m_one_thread_timeout_usec = timeout; + } + bool GetTryAllThreads () const { @@ -335,6 +359,20 @@ public: SetDebug(bool b) { m_debug = b; + if (m_debug) + m_generate_debug_info = true; + } + + bool + GetGenerateDebugInfo() const + { + return m_generate_debug_info; + } + + void + SetGenerateDebugInfo(bool b) + { + m_generate_debug_info = b; } bool @@ -348,6 +386,34 @@ public: { m_trap_exceptions = b; } + + void + SetCancelCallback (lldb::ExpressionCancelCallback callback, void *baton) + { + m_cancel_callback_baton = baton; + m_cancel_callback = callback; + } + + bool + InvokeCancelCallback (lldb::ExpressionEvaluationPhase phase) const + { + if (m_cancel_callback == nullptr) + return false; + else + return m_cancel_callback (phase, m_cancel_callback_baton); + } + + void + SetResultIsInternal (bool b) + { + m_result_is_internal = b; + } + + bool + GetResultIsInternal () const + { + return m_result_is_internal; + } private: ExecutionPolicy m_execution_policy; @@ -360,8 +426,13 @@ private: bool m_stop_others; bool m_debug; bool m_trap_exceptions; + bool m_generate_debug_info; + bool m_result_is_internal; lldb::DynamicValueType m_use_dynamic; uint32_t m_timeout_usec; + uint32_t m_one_thread_timeout_usec; + lldb::ExpressionCancelCallback m_cancel_callback; + void *m_cancel_callback_baton; }; //---------------------------------------------------------------------- @@ -513,7 +584,7 @@ public: /// in a target. /// /// @param[in] s - /// The stream to which to dump the object descripton. + /// The stream to which to dump the object description. //------------------------------------------------------------------ void Dump (Stream *s, lldb::DescriptionLevel description_level); @@ -1086,7 +1157,7 @@ public: // we provide a way for expressions to be evaluated from the Target itself. // If an expression is going to be run, then it should have a frame filled // in in th execution context. - ExecutionResults + lldb::ExpressionResults EvaluateExpression (const char *expression, StackFrame *frame, lldb::ValueObjectSP &result_valobj_sp, diff --git a/include/lldb/Target/TargetList.h b/include/lldb/Target/TargetList.h index 41404e11c7fa..6abf13e8704c 100644 --- a/include/lldb/Target/TargetList.h +++ b/include/lldb/Target/TargetList.h @@ -121,7 +121,7 @@ public: //------------------------------------------------------------------ /// Delete a Target object from the list. /// - /// When clients are done with the Target objets, this function + /// When clients are done with the Target objects, this function /// should be called to release the memory associated with a target /// object. /// diff --git a/include/lldb/Target/Thread.h b/include/lldb/Target/Thread.h index 20687e977bff..cba09e164105 100644 --- a/include/lldb/Target/Thread.h +++ b/include/lldb/Target/Thread.h @@ -14,6 +14,7 @@ #include "lldb/Host/Mutex.h" #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Event.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Core/UserID.h" #include "lldb/Core/UserSettingsController.h" #include "lldb/Target/ExecutionContextScope.h" @@ -49,6 +50,12 @@ public: bool GetTraceEnabledState() const; + + bool + GetStepInAvoidsNoDebug () const; + + bool + GetStepOutAvoidsNoDebug () const; }; typedef std::shared_ptr ThreadPropertiesSP; @@ -153,7 +160,25 @@ public: static const ThreadPropertiesSP & GetGlobalProperties(); - Thread (Process &process, lldb::tid_t tid); + //------------------------------------------------------------------ + /// Constructor + /// + /// @param [in] process + /// + /// @param [in] tid + /// + /// @param [in] use_invalid_index_id + /// Optional parameter, defaults to false. The only subclass that + /// is likely to set use_invalid_index_id == true is the HistoryThread + /// class. In that case, the Thread we are constructing represents + /// a thread from earlier in the program execution. We may have the + /// tid of the original thread that they represent but we don't want + /// to reuse the IndexID of that thread, or create a new one. If a + /// client wants to know the original thread's IndexID, they should use + /// Thread::GetExtendedBacktraceOriginatingIndexID(). + //------------------------------------------------------------------ + Thread (Process &process, lldb::tid_t tid, bool use_invalid_index_id = false); + virtual ~Thread(); lldb::ProcessSP @@ -185,10 +210,22 @@ public: { return m_resume_state; } - + + // This sets the "external resume state" of the thread. If the thread is suspended here, it should never + // get scheduled. Note that just because a thread is marked as "running" does not mean we will let it run in + // a given bit of process control. For instance "step" tries to stay on the selected thread it was issued on, + // which may involve suspending other threads temporarily. This temporary suspension is NOT reflected in the + // state set here and reported in GetResumeState. + // + // If you are just preparing all threads to run, you should not override the threads that are + // marked as suspended by the debugger. In that case, pass override_suspend = false. If you want + // to force the thread to run (e.g. the "thread continue" command, or are resetting the state + // (e.g. in SBThread::Resume()), then pass true to override_suspend. void - SetResumeState (lldb::StateType state) + SetResumeState (lldb::StateType state, bool override_suspend = false) { + if (m_resume_state == lldb::eStateSuspended && !override_suspend) + return; m_resume_state = state; } @@ -270,6 +307,28 @@ public: return NULL; } + //------------------------------------------------------------------ + /// Retrieve a dictionary of information about this thread + /// + /// On Mac OS X systems there may be voucher information. + /// The top level dictionary returned will have an "activity" key and the + /// value of the activity is a dictionary. Keys in that dictionary will + /// be "name" and "id", among others. + /// There may also be "trace_messages" (an array) with each entry in that array + /// being a dictionary (keys include "message" with the text of the trace + /// message). + //------------------------------------------------------------------ + StructuredData::ObjectSP + GetExtendedInfo () + { + if (m_extended_info_fetched == false) + { + m_extended_info = FetchThreadExtendedInfo (); + m_extended_info_fetched = true; + } + return m_extended_info; + } + virtual const char * GetName () { @@ -281,6 +340,21 @@ public: { } + //------------------------------------------------------------------ + /// Retrieve the Queue ID for the queue currently using this Thread + /// + /// If this Thread is doing work on behalf of a libdispatch/GCD queue, + /// retrieve the QueueID. + /// + /// This is a unique identifier for the libdispatch/GCD queue in a + /// process. Often starting at 1 for the initial system-created + /// queues and incrementing, a QueueID will not be reused for a + /// different queue during the lifetime of a proces. + /// + /// @return + /// A QueueID if the Thread subclass implements this, else + /// LLDB_INVALID_QUEUE_ID. + //------------------------------------------------------------------ virtual lldb::queue_id_t GetQueueID () { @@ -292,6 +366,16 @@ public: { } + //------------------------------------------------------------------ + /// Retrieve the Queue name for the queue currently using this Thread + /// + /// If this Thread is doing work on behalf of a libdispatch/GCD queue, + /// retrieve the Queue name. + /// + /// @return + /// The Queue name, if the Thread subclass implements this, else + /// NULL. + //------------------------------------------------------------------ virtual const char * GetQueueName () { @@ -303,6 +387,44 @@ public: { } + //------------------------------------------------------------------ + /// Retrieve the Queue for this thread, if any. + /// + /// @return + /// A QueueSP for the queue that is currently associated with this + /// thread. + /// An empty shared pointer indicates that this thread is not + /// associated with a queue, or libdispatch queues are not + /// supported on this target. + //------------------------------------------------------------------ + virtual lldb::QueueSP + GetQueue () + { + return lldb::QueueSP(); + } + + //------------------------------------------------------------------ + /// Retrieve the address of the libdispatch_queue_t struct for queue + /// currently using this Thread + /// + /// If this Thread is doing work on behalf of a libdispatch/GCD queue, + /// retrieve the address of the libdispatch_queue_t structure describing + /// the queue. + /// + /// This address may be reused for different queues later in the Process + /// lifetime and should not be used to identify a queue uniquely. Use + /// the GetQueueID() call for that. + /// + /// @return + /// The Queue's libdispatch_queue_t address if the Thread subclass + /// implements this, else LLDB_INVALID_ADDRESS. + //------------------------------------------------------------------ + virtual lldb::addr_t + GetQueueLibdispatchQueueAddress () + { + return LLDB_INVALID_ADDRESS; + } + virtual uint32_t GetStackFrameCount() { @@ -412,6 +534,9 @@ public: void DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx); + bool + GetDescription (Stream &s, lldb::DescriptionLevel level, bool json_output); + //------------------------------------------------------------------ /// Default implementation for stepping into. /// @@ -422,17 +547,22 @@ public: /// If true and the frame has debug info, then do a source level /// step in, else do a single instruction step in. /// - /// @param[in] avoid_code_without_debug_info + /// @param[in] step_in_avoids_code_without_debug_info /// If \a true, then avoid stepping into code that doesn't have - /// debug info, else step into any code regardless of wether it + /// debug info, else step into any code regardless of whether it /// has debug info. /// + /// @param[in] step_out_avoids_code_without_debug_info + /// If \a true, then if you step out to code with no debug info, keep + /// stepping out till you get to code with debug info. + /// /// @return /// An error that describes anything that went wrong //------------------------------------------------------------------ virtual Error StepIn (bool source_step, - bool avoid_code_without_debug_info); + LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate, + LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate); //------------------------------------------------------------------ /// Default implementation for stepping over. @@ -448,7 +578,8 @@ public: /// An error that describes anything that went wrong //------------------------------------------------------------------ virtual Error - StepOver (bool source_step); + StepOver (bool source_step, + LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate); //------------------------------------------------------------------ /// Default implementation for stepping out. @@ -487,6 +618,19 @@ public: virtual lldb::addr_t GetThreadLocalData (const lldb::ModuleSP module); + //------------------------------------------------------------------ + /// Check whether this thread is safe to run functions + /// + /// The SystemRuntime may know of certain thread states (functions in + /// process of execution, for instance) which can make it unsafe for + /// functions to be called. + /// + /// @return + /// True if it is safe to call functions on this thread. + /// False if function calls should be avoided on this thread. + //------------------------------------------------------------------ + virtual bool + SafeToCallFunctions (); //------------------------------------------------------------------ // Thread Plan Providers: @@ -574,14 +718,19 @@ public: /// @param[in] stop_other_threads /// \b true if we will stop other threads while we single step this one. /// + /// @param[in] step_out_avoids_code_without_debug_info + /// If eLazyBoolYes, if the step over steps out it will continue to step out till it comes to a frame with debug info. + /// If eLazyBoolCalculate, we will consult the default set in the thread. + /// /// @return /// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued. //------------------------------------------------------------------ virtual lldb::ThreadPlanSP QueueThreadPlanForStepOverRange (bool abort_other_plans, - const AddressRange &range, - const SymbolContext &addr_context, - lldb::RunMode stop_other_threads); + const AddressRange &range, + const SymbolContext &addr_context, + lldb::RunMode stop_other_threads, + LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate); //------------------------------------------------------------------ /// Queues the plan used to step through an address range, stepping into functions. @@ -609,19 +758,25 @@ public: /// @param[in] stop_other_threads /// \b true if we will stop other threads while we single step this one. /// - /// @param[in] avoid_code_without_debug_info - /// If \b true we will step out if we step into code with no debug info. + /// @param[in] step_in_avoids_code_without_debug_info + /// If eLazyBoolYes we will step out if we step into code with no debug info. + /// If eLazyBoolCalculate we will consult the default set in the thread. + /// + /// @param[in] step_out_avoids_code_without_debug_info + /// If eLazyBoolYes, if the step over steps out it will continue to step out till it comes to a frame with debug info. + /// If eLazyBoolCalculate, it will consult the default set in the thread. /// /// @return /// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued. //------------------------------------------------------------------ virtual lldb::ThreadPlanSP QueueThreadPlanForStepInRange (bool abort_other_plans, - const AddressRange &range, - const SymbolContext &addr_context, - const char *step_in_target, - lldb::RunMode stop_other_threads, - bool avoid_code_without_debug_info); + const AddressRange &range, + const SymbolContext &addr_context, + const char *step_in_target, + lldb::RunMode stop_other_threads, + LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate, + LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate); //------------------------------------------------------------------ /// Queue the plan used to step out of the function at the current PC of @@ -648,6 +803,10 @@ public: /// @param[in] run_vote /// See standard meanings for the stop & run votes in ThreadPlan.h. /// + /// @param[in] step_out_avoids_code_without_debug_info + /// If eLazyBoolYes, if the step over steps out it will continue to step out till it comes to a frame with debug info. + /// If eLazyBoolCalculate, it will consult the default set in the thread. + /// /// @return /// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued. //------------------------------------------------------------------ @@ -658,7 +817,46 @@ public: bool stop_other_threads, Vote stop_vote, // = eVoteYes, Vote run_vote, // = eVoteNoOpinion); - uint32_t frame_idx); + uint32_t frame_idx, + LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate); + + //------------------------------------------------------------------ + /// Queue the plan used to step out of the function at the current PC of + /// a thread. This version does not consult the should stop here callback, and should only + /// be used by other thread plans when they need to retain control of the step out. + /// + /// @param[in] abort_other_plans + /// \b true if we discard the currently queued plans and replace them with this one. + /// Otherwise this plan will go on the end of the plan stack. + /// + /// @param[in] addr_context + /// When dealing with stepping through inlined functions the current PC is not enough information to know + /// what "step" means. For instance a series of nested inline functions might start at the same address. + // The \a addr_context provides the current symbol context the step + /// is supposed to be out of. + // FIXME: Currently unused. + /// + /// @param[in] first_insn + /// \b true if this is the first instruction of a function. + /// + /// @param[in] stop_other_threads + /// \b true if we will stop other threads while we single step this one. + /// + /// @param[in] stop_vote + /// @param[in] run_vote + /// See standard meanings for the stop & run votes in ThreadPlan.h. + /// + /// @return + /// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued. + //------------------------------------------------------------------ + virtual lldb::ThreadPlanSP + QueueThreadPlanForStepOutNoShouldStop (bool abort_other_plans, + SymbolContext *addr_context, + bool first_insn, + bool stop_other_threads, + Vote stop_vote, // = eVoteYes, + Vote run_vote, // = eVoteNoOpinion); + uint32_t frame_idx); //------------------------------------------------------------------ /// Gets the plan used to step through the code that steps from a function @@ -767,6 +965,17 @@ public: lldb::ValueObjectSP GetReturnValueObject (); + //------------------------------------------------------------------ + /// Gets the outer-most expression variable from the completed plans + /// + /// @return + /// A ClangExpressionVariableSP, either empty if there is no + /// plan completed an expression during the current stop + /// or the expression variable that was made for the completed expression. + //------------------------------------------------------------------ + lldb::ClangExpressionVariableSP + GetExpressionVariable (); + //------------------------------------------------------------------ /// Checks whether the given plan is in the completed plans for this /// stop. @@ -1066,6 +1275,13 @@ protected: return false; } + // Subclasses that have a way to get an extended info dictionary for this thread should + // fill + virtual lldb_private::StructuredData::ObjectSP + FetchThreadExtendedInfo () + { + return StructuredData::ObjectSP(); + } lldb::StackFrameListSP GetStackFrameList (); @@ -1091,11 +1307,13 @@ protected: int m_resume_signal; ///< The signal that should be used when continuing this thread. lldb::StateType m_resume_state; ///< This state is used to force a thread to be suspended from outside the ThreadPlan logic. lldb::StateType m_temporary_resume_state; ///< This state records what the thread was told to do by the thread plan logic for the current resume. - /// It gets set in Thread::ShoudResume. + /// It gets set in Thread::ShouldResume. std::unique_ptr m_unwinder_ap; bool m_destroy_called; // This is used internally to make sure derived Thread classes call DestroyThread. LazyBool m_override_should_notify; private: + bool m_extended_info_fetched; // Have we tried to retrieve the m_extended_info for this thread? + StructuredData::ObjectSP m_extended_info; // The extended info for this thread //------------------------------------------------------------------ // For Thread only //------------------------------------------------------------------ diff --git a/include/lldb/Target/ThreadPlan.h b/include/lldb/Target/ThreadPlan.h index 3c83fd1b9630..1f20841906d3 100644 --- a/include/lldb/Target/ThreadPlan.h +++ b/include/lldb/Target/ThreadPlan.h @@ -501,11 +501,26 @@ public: return m_thread.GetStopInfo (); } + // If the completion of the thread plan stepped out of a function, the return value of the function + // might have been captured by the thread plan (currently only ThreadPlanStepOut does this.) + // If so, the ReturnValueObject can be retrieved from here. + virtual lldb::ValueObjectSP GetReturnValueObject () { return lldb::ValueObjectSP(); } + + // If the thread plan managing the evaluation of a user expression lives longer than the command + // that instigated the expression (generally because the expression evaluation hit a breakpoint, and + // the user regained control at that point) a subsequent process control command step/continue/etc. might + // complete the expression evaluations. If so, the result of the expression evaluation will show up here. + + virtual lldb::ClangExpressionVariableSP + GetExpressionVariable () + { + return lldb::ClangExpressionVariableSP(); + } // If a thread plan stores the state before it was run, then you might // want to restore the state when it is done. This will do that job. @@ -524,6 +539,27 @@ public: return false; } + virtual bool + SetIterationCount (size_t count) + { + if (m_takes_iteration_count) + { + // Don't tell me to do something 0 times... + if (count == 0) + return false; + m_iteration_count = count; + } + return m_takes_iteration_count; + } + + virtual size_t + GetIterationCount () + { + if (!m_takes_iteration_count) + return 0; + else + return m_iteration_count; + } protected: //------------------------------------------------------------------ // Classes that inherit from ThreadPlan can see and modify these @@ -578,6 +614,8 @@ protected: Thread &m_thread; Vote m_stop_vote; Vote m_run_vote; + bool m_takes_iteration_count = false; + int32_t m_iteration_count = 1; private: //------------------------------------------------------------------ diff --git a/include/lldb/Target/ThreadPlanCallFunction.h b/include/lldb/Target/ThreadPlanCallFunction.h index 18f1d0facbf6..12200ab76553 100644 --- a/include/lldb/Target/ThreadPlanCallFunction.h +++ b/include/lldb/Target/ThreadPlanCallFunction.h @@ -52,9 +52,6 @@ public: virtual bool StopOthers (); - virtual void - SetStopOthers (bool new_value); - virtual lldb::StateType GetPlanRunState (); @@ -128,7 +125,10 @@ public: m_takedown_done = true; } -protected: + virtual void + SetStopOthers (bool new_value); + +protected: void ReportRegisterState (const char *message); virtual bool diff --git a/include/lldb/Target/ThreadPlanCallUserExpression.h b/include/lldb/Target/ThreadPlanCallUserExpression.h index 5eb7cc1cd452..67ac642de7bd 100644 --- a/include/lldb/Target/ThreadPlanCallUserExpression.h +++ b/include/lldb/Target/ThreadPlanCallUserExpression.h @@ -40,21 +40,35 @@ public: GetDescription (Stream *s, lldb::DescriptionLevel level); virtual void - WillPop () - { - ThreadPlanCallFunction::WillPop(); - if (m_user_expression_sp) - m_user_expression_sp.reset(); - } + WillPop (); virtual lldb::StopInfoSP GetRealStopInfo(); + virtual bool + MischiefManaged (); + + void + TransferExpressionOwnership () + { + m_manage_materialization = true; + } + + virtual lldb::ClangExpressionVariableSP + GetExpressionVariable () + { + return m_result_var_sp; + } + protected: private: ClangUserExpression::ClangUserExpressionSP m_user_expression_sp; // This is currently just used to ensure the // User expression the initiated this ThreadPlan // lives as long as the thread plan does. + bool m_manage_materialization = false; + lldb::ClangExpressionVariableSP m_result_var_sp; // If we are left to manage the materialization, + // then stuff the result expression variable here. + DISALLOW_COPY_AND_ASSIGN (ThreadPlanCallUserExpression); }; diff --git a/include/lldb/Target/ThreadPlanShouldStopHere.h b/include/lldb/Target/ThreadPlanShouldStopHere.h index 62068b78ae4e..26e4a1ec4fe7 100644 --- a/include/lldb/Target/ThreadPlanShouldStopHere.h +++ b/include/lldb/Target/ThreadPlanShouldStopHere.h @@ -21,8 +21,9 @@ namespace lldb_private { // This is an interface that ThreadPlans can adopt to allow flexible modifications of the behavior // when a thread plan comes to a place where it would ordinarily stop. If such modification makes // sense for your plan, inherit from this class, and when you would be about to stop (in your ShouldStop -// method), call InvokeShouldStopHereCallback, and if that returns a non-NULL plan, execute that -// plan instead of stopping. +// method), call InvokeShouldStopHereCallback, passing in the frame comparison between where the step operation +// started and where you arrived. If it returns true, then QueueStepOutFromHere will queue the plan +// to execute instead of stopping. // // The classic example of the use of this is ThreadPlanStepInRange not stopping in frames that have // no debug information. @@ -34,27 +35,84 @@ namespace lldb_private { class ThreadPlanShouldStopHere { public: + struct ThreadPlanShouldStopHereCallbacks + { + ThreadPlanShouldStopHereCallbacks() + { + should_stop_here_callback = nullptr; + step_from_here_callback = nullptr; + } + + ThreadPlanShouldStopHereCallbacks(ThreadPlanShouldStopHereCallback should_stop, + ThreadPlanStepFromHereCallback step_from_here) + { + should_stop_here_callback = should_stop; + step_from_here_callback = step_from_here; + } + + void + Clear() + { + should_stop_here_callback = nullptr; + step_from_here_callback = nullptr; + } + + ThreadPlanShouldStopHereCallback should_stop_here_callback; + ThreadPlanStepFromHereCallback step_from_here_callback; + }; + enum { eNone = 0, - eAvoidInlines = (1 << 0), - eAvoidNoDebug = (1 << 1) + eAvoidInlines = (1 << 0), + eStepInAvoidNoDebug = (1 << 1), + eStepOutAvoidNoDebug = (1 << 2) }; //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ + ThreadPlanShouldStopHere (ThreadPlan *owner); + ThreadPlanShouldStopHere (ThreadPlan *owner, - ThreadPlanShouldStopHereCallback callback = NULL, + const ThreadPlanShouldStopHereCallbacks *callbacks, void *baton = NULL); virtual ~ThreadPlanShouldStopHere(); - + + // Set the ShouldStopHere callbacks. Pass in null to clear them and have no special behavior (though you + // can also call ClearShouldStopHereCallbacks for that purpose. If you pass in a valid pointer, it will + // adopt the non-null fields, and any null fields will be set to the default values. + void - SetShouldStopHereCallback (ThreadPlanShouldStopHereCallback callback, void *baton); + SetShouldStopHereCallbacks (const ThreadPlanShouldStopHereCallbacks *callbacks, void *baton) + { + if (callbacks) + { + m_callbacks = *callbacks; + if (!m_callbacks.should_stop_here_callback) + m_callbacks.should_stop_here_callback = ThreadPlanShouldStopHere::DefaultShouldStopHereCallback; + if (!m_callbacks.step_from_here_callback) + m_callbacks.step_from_here_callback = ThreadPlanShouldStopHere::DefaultStepFromHereCallback; + } + else + { + ClearShouldStopHereCallbacks (); + } + m_baton = baton; + } + + void + ClearShouldStopHereCallbacks() + { + m_callbacks.Clear(); + } + bool + InvokeShouldStopHereCallback (lldb::FrameComparison operation); + lldb::ThreadPlanSP - InvokeShouldStopHereCallback (); + CheckShouldStopHereAndQueueStepOut (lldb::FrameComparison operation); lldb_private::Flags & GetFlags () @@ -69,13 +127,22 @@ public: } protected: + static bool + DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, void *baton); + + static lldb::ThreadPlanSP + DefaultStepFromHereCallback (ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, void *baton); + + virtual lldb::ThreadPlanSP + QueueStepOutFromHerePlan (Flags &flags, lldb::FrameComparison operation); + // Implement this, and call it in the plan's constructor to set the default flags. virtual void SetFlagsToDefault () = 0; //------------------------------------------------------------------ // Classes that inherit from ThreadPlanShouldStopHere can see and modify these //------------------------------------------------------------------ - ThreadPlanShouldStopHereCallback m_callback; + ThreadPlanShouldStopHereCallbacks m_callbacks; void * m_baton; ThreadPlan *m_owner; lldb_private::Flags m_flags; diff --git a/include/lldb/Target/ThreadPlanStepInRange.h b/include/lldb/Target/ThreadPlanStepInRange.h index 2f741f179bd4..3a22e97e30d0 100644 --- a/include/lldb/Target/ThreadPlanStepInRange.h +++ b/include/lldb/Target/ThreadPlanStepInRange.h @@ -30,13 +30,17 @@ public: ThreadPlanStepInRange (Thread &thread, const AddressRange &range, const SymbolContext &addr_context, - lldb::RunMode stop_others); - + lldb::RunMode stop_others, + LazyBool step_in_avoids_code_without_debug_info, + LazyBool step_out_avoids_code_without_debug_info); + ThreadPlanStepInRange (Thread &thread, const AddressRange &range, const SymbolContext &addr_context, const char *step_into_function_name, - lldb::RunMode stop_others); + lldb::RunMode stop_others, + LazyBool step_in_avoids_code_without_debug_info, + LazyBool step_out_avoids_code_without_debug_info); virtual ~ThreadPlanStepInRange (); @@ -54,9 +58,6 @@ public: m_step_into_target.SetCString(target); } - static lldb::ThreadPlanSP - DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, void *baton); - static void SetDefaultFlagValue (uint32_t new_value); @@ -64,13 +65,26 @@ public: IsVirtualStep(); protected: + static bool + DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, void *baton); + virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan); virtual bool DoPlanExplainsStop (Event *event_ptr); virtual void - SetFlagsToDefault (); + SetFlagsToDefault () + { + GetFlags().Set(ThreadPlanStepInRange::s_default_flag_values); + } + + void + SetCallbacks() + { + ThreadPlanShouldStopHere::ThreadPlanShouldStopHereCallbacks callbacks(ThreadPlanStepInRange::DefaultShouldStopHereCallback, nullptr); + SetShouldStopHereCallbacks (&callbacks, nullptr); + } bool FrameMatchesAvoidCriteria (); @@ -81,20 +95,23 @@ private: Thread::QueueThreadPlanForStepOverRange (bool abort_other_plans, const AddressRange &range, const SymbolContext &addr_context, - lldb::RunMode stop_others); + lldb::RunMode stop_others, + LazyBool avoid_code_without_debug_info); friend lldb::ThreadPlanSP Thread::QueueThreadPlanForStepInRange (bool abort_other_plans, const AddressRange &range, const SymbolContext &addr_context, const char *step_in_target, lldb::RunMode stop_others, - bool avoid_code_without_debug_info); - + LazyBool step_in_avoids_code_without_debug_info, + LazyBool step_out_avoids_code_without_debug_info); + void SetupAvoidNoDebug(LazyBool step_in_avoids_code_without_debug_info, + LazyBool step_out_avoids_code_without_debug_info); // Need an appropriate marker for the current stack so we can tell step out // from step in. - static uint32_t s_default_flag_values; + static uint32_t s_default_flag_values; // These are the default flag values for the ThreadPlanStepThrough. lldb::ThreadPlanSP m_sub_plan_sp; // Keep track of the last plan we were running. If it fails, we should stop. std::unique_ptr m_avoid_regexp_ap; bool m_step_past_prologue; // FIXME: For now hard-coded to true, we could put a switch in for this if there's diff --git a/include/lldb/Target/ThreadPlanStepInstruction.h b/include/lldb/Target/ThreadPlanStepInstruction.h index eb4a64bcbc84..86069ffd9eb5 100644 --- a/include/lldb/Target/ThreadPlanStepInstruction.h +++ b/include/lldb/Target/ThreadPlanStepInstruction.h @@ -32,6 +32,7 @@ public: virtual lldb::StateType GetPlanRunState (); virtual bool WillStop (); virtual bool MischiefManaged (); + virtual bool IsPlanStale (); protected: virtual bool DoPlanExplainsStop (Event *event_ptr); @@ -41,6 +42,7 @@ protected: bool stop_others, Vote stop_vote, Vote run_vote); + void SetUpState (); private: friend lldb::ThreadPlanSP diff --git a/include/lldb/Target/ThreadPlanStepOut.h b/include/lldb/Target/ThreadPlanStepOut.h index 2737978a4edc..8c140dc9d95d 100644 --- a/include/lldb/Target/ThreadPlanStepOut.h +++ b/include/lldb/Target/ThreadPlanStepOut.h @@ -16,10 +16,12 @@ // Project includes #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" +#include "lldb/Target/ThreadPlanShouldStopHere.h" namespace lldb_private { -class ThreadPlanStepOut : public ThreadPlan +class ThreadPlanStepOut : public ThreadPlan, + public ThreadPlanShouldStopHere { public: ThreadPlanStepOut (Thread &thread, @@ -28,7 +30,8 @@ public: bool stop_others, Vote stop_vote, Vote run_vote, - uint32_t frame_idx); + uint32_t frame_idx, + LazyBool step_out_avoids_code_without_debug_info); virtual ~ThreadPlanStepOut (); @@ -48,21 +51,29 @@ public: } protected: + virtual void + SetFlagsToDefault () + { + GetFlags().Set(ThreadPlanStepOut::s_default_flag_values); + } + virtual bool DoPlanExplainsStop (Event *event_ptr); virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan); bool QueueInlinedStepPlan (bool queue_now); private: - SymbolContext *m_step_from_context; + static uint32_t s_default_flag_values; // These are the default flag values for the ThreadPlanStepThrough. + lldb::addr_t m_step_from_insn; StackID m_step_out_to_id; StackID m_immediate_step_from_id; lldb::break_id_t m_return_bp_id; lldb::addr_t m_return_addr; - bool m_first_insn; bool m_stop_others; - lldb::ThreadPlanSP m_step_through_inline_plan_sp; - lldb::ThreadPlanSP m_step_out_plan_sp; + lldb::ThreadPlanSP m_step_out_to_inline_plan_sp; // This plan implements step out to the real function containing + // an inlined frame so we can then step out of that. + lldb::ThreadPlanSP m_step_through_inline_plan_sp; // This plan then steps past the inlined frame(s). + lldb::ThreadPlanSP m_step_out_further_plan_sp; // This plan keeps stepping out if ShouldStopHere told us to. Function *m_immediate_step_from_function; lldb::ValueObjectSP m_return_valobj_sp; @@ -73,8 +84,10 @@ private: bool stop_others, Vote stop_vote, Vote run_vote, - uint32_t frame_idx); + uint32_t frame_idx, + LazyBool step_out_avoids_code_without_debug_info); + void SetupAvoidNoDebug(LazyBool step_out_avoids_code_without_debug_info); // Need an appropriate marker for the current stack so we can tell step out // from step in. diff --git a/include/lldb/Target/ThreadPlanStepOverRange.h b/include/lldb/Target/ThreadPlanStepOverRange.h index 2cb5288272ea..d47c6c9429d5 100644 --- a/include/lldb/Target/ThreadPlanStepOverRange.h +++ b/include/lldb/Target/ThreadPlanStepOverRange.h @@ -21,14 +21,16 @@ namespace lldb_private { -class ThreadPlanStepOverRange : public ThreadPlanStepRange +class ThreadPlanStepOverRange : public ThreadPlanStepRange, + ThreadPlanShouldStopHere { public: ThreadPlanStepOverRange (Thread &thread, const AddressRange &range, const SymbolContext &addr_context, - lldb::RunMode stop_others); + lldb::RunMode stop_others, + LazyBool step_out_avoids_no_debug); virtual ~ThreadPlanStepOverRange (); @@ -38,9 +40,20 @@ public: protected: virtual bool DoPlanExplainsStop (Event *event_ptr); virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan); - + + virtual void + SetFlagsToDefault () + { + GetFlags().Set(ThreadPlanStepOverRange::s_default_flag_values); + } + + + private: + static uint32_t s_default_flag_values; + + void SetupAvoidNoDebug(LazyBool step_out_avoids_code_without_debug_info); bool IsEquivalentContext(const SymbolContext &context); bool m_first_resume; diff --git a/include/lldb/Target/ThreadPlanStepRange.h b/include/lldb/Target/ThreadPlanStepRange.h index 486fd6528390..3487e9ad66cb 100644 --- a/include/lldb/Target/ThreadPlanStepRange.h +++ b/include/lldb/Target/ThreadPlanStepRange.h @@ -77,6 +77,7 @@ protected: std::vector m_address_ranges; lldb::RunMode m_stop_others; StackID m_stack_id; // Use the stack ID so we can tell step out from step in. + StackID m_parent_stack_id; // Use the parent stack ID so we can identify tail calls and the like. bool m_no_more_plans; // Need this one so we can tell if we stepped into a call, // but can't continue, in which case we are done. bool m_first_run_event; // We want to broadcast only one running event, our first. diff --git a/include/lldb/Target/UnwindAssembly.h b/include/lldb/Target/UnwindAssembly.h index 254382ac029d..963949cf07d5 100644 --- a/include/lldb/Target/UnwindAssembly.h +++ b/include/lldb/Target/UnwindAssembly.h @@ -32,6 +32,11 @@ public: Thread& thread, UnwindPlan& unwind_plan) = 0; + virtual bool + AugmentUnwindPlanFromCallSite (AddressRange& func, + Thread& thread, + UnwindPlan& unwind_plan) = 0; + virtual bool GetFastUnwindPlan (AddressRange& func, Thread& thread, diff --git a/include/lldb/Utility/CleanUp.h b/include/lldb/Utility/CleanUp.h index ab15d1999b7d..9dd3ca5fe12b 100644 --- a/include/lldb/Utility/CleanUp.h +++ b/include/lldb/Utility/CleanUp.h @@ -27,7 +27,7 @@ namespace lldb_utility { // file descriptors, opaque handles, pointers, etc). If more complex // type T objects are desired, we need to probably specialize this class // to take "const T&" for all input T parameters. Yet if a type T is -// complex already it might be better to build the cleanup funcionality +// complex already it might be better to build the cleanup functionality // into T. // // The cleanup function must take one argument that is of type T. @@ -163,7 +163,7 @@ public: //---------------------------------------------------------------------- // Cancels the cleanup that would have been called on "m_current_value" // if it was valid. This function can be used to release the value - // contained in this object so ownership can be transfered to the caller. + // contained in this object so ownership can be transferred to the caller. //---------------------------------------------------------------------- value_type release () @@ -296,7 +296,7 @@ public: //---------------------------------------------------------------------- // Cancels the cleanup that would have been called on "m_current_value" // if it was valid. This function can be used to release the value - // contained in this object so ownership can be transfered to the caller. + // contained in this object so ownership can be transferred to the caller. //---------------------------------------------------------------------- value_type release () diff --git a/include/lldb/Utility/PseudoTerminal.h b/include/lldb/Utility/PseudoTerminal.h index c79800fab75c..6ee598cefe08 100644 --- a/include/lldb/Utility/PseudoTerminal.h +++ b/include/lldb/Utility/PseudoTerminal.h @@ -23,7 +23,7 @@ namespace lldb_utility { /// @class PseudoTerminal PseudoTerminal.h "lldb/Core/PseudoTerminal.h" /// @brief A pseudo terminal helper class. /// -/// The pseudo terminal class abtracts the use of pseudo terminals on +/// The pseudo terminal class abstracts the use of pseudo terminals on /// the host system. //---------------------------------------------------------------------- class PseudoTerminal @@ -46,7 +46,7 @@ public: /// Destructor /// /// The destructor will close the master and slave file descriptors - /// if they are valid and ownwership has not been released using + /// if they are valid and ownership has not been released using /// one of: /// @li PseudoTerminal::ReleaseMasterFileDescriptor() /// @li PseudoTerminal::ReleaseSaveFileDescriptor() diff --git a/include/lldb/Utility/SafeMachO.h b/include/lldb/Utility/SafeMachO.h new file mode 100644 index 000000000000..2a831ed89b80 --- /dev/null +++ b/include/lldb/Utility/SafeMachO.h @@ -0,0 +1,113 @@ +//===-- SafeMachO.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_SafeMachO_h_ +#define liblldb_SafeMachO_h_ + +// This header file is required to work around collisions between the defines in mach/machine.h, and enum members +// of the same name in llvm's MachO.h. If you want to use llvm/Support/MachO.h, use this file instead. +// The caveats are: +// 1) You can only use the MachO.h enums, you can't use the defines. That won't make a difference since the values +// are the same. +// 2) If you need any header file that relies on mach/machine.h, you must include that first. +// 3) This isn't a total solution, it doesn't undef every define that MachO.h has borrowed from various system headers, +// only the ones that come from mach/machine.h because that is the one we ended up pulling in from various places. +// + +#undef CPU_ARCH_MASK +#undef CPU_ARCH_ABI64 + +#undef CPU_TYPE_ANY +#undef CPU_TYPE_X86 +#undef CPU_TYPE_I386 +#undef CPU_TYPE_X86_64 +#undef CPU_TYPE_MC98000 +#undef CPU_TYPE_ARM +#undef CPU_TYPE_ARM64 +#undef CPU_TYPE_SPARC +#undef CPU_TYPE_POWERPC +#undef CPU_TYPE_POWERPC64 + +#undef CPU_SUB_TYPE_MASK +#undef CPU_SUB_TYPE_LIB64 + +#undef CPU_SUBTYPE_MULTIPLE + +#undef CPU_SUBTYPE_I386_ALL +#undef CPU_SUBTYPE_386 +#undef CPU_SUBTYPE_486 +#undef CPU_SUBTYPE_486SX +#undef CPU_SUBTYPE_586 +#undef CPU_SUBTYPE_PENT +#undef CPU_SUBTYPE_PENTPRO +#undef CPU_SUBTYPE_PENTII_M3 +#undef CPU_SUBTYPE_PENTII_M5 +#undef CPU_SUBTYPE_CELERON +#undef CPU_SUBTYPE_CELERON_MOBILE +#undef CPU_SUBTYPE_PENTIUM_3 +#undef CPU_SUBTYPE_PENTIUM_3_M +#undef CPU_SUBTYPE_PENTIUM_3_XEON +#undef CPU_SUBTYPE_PENTIUM_M +#undef CPU_SUBTYPE_PENTIUM_4 +#undef CPU_SUBTYPE_PENTIUM_4_M +#undef CPU_SUBTYPE_ITANIUM +#undef CPU_SUBTYPE_ITANIUM_2 +#undef CPU_SUBTYPE_XEON +#undef CPU_SUBTYPE_XEON_MP + +#undef CPU_SUBTYPE_X86_ALL +#undef CPU_SUBTYPE_X86_64_ALL +#undef CPU_SUBTYPE_X86_ARCH1 +#undef CPU_SUBTYPE_X86_64_H + +#undef CPU_SUBTYPE_INTEL +#undef CPU_SUBTYPE_INTEL_FAMILY +#undef CPU_SUBTYPE_INTEL_FAMILY_MAX +#undef CPU_SUBTYPE_INTEL_MODEL +#undef CPU_SUBTYPE_INTEL_MODEL_ALL + +#undef CPU_SUBTYPE_ARM +#undef CPU_SUBTYPE_ARM_ALL +#undef CPU_SUBTYPE_ARM_V4T +#undef CPU_SUBTYPE_ARM_V6 +#undef CPU_SUBTYPE_ARM_V5 +#undef CPU_SUBTYPE_ARM_V5TEJ +#undef CPU_SUBTYPE_ARM_XSCALE +#undef CPU_SUBTYPE_ARM_V7 + +#undef CPU_SUBTYPE_ARM_V7S +#undef CPU_SUBTYPE_ARM_V7K +#undef CPU_SUBTYPE_ARM_V6M +#undef CPU_SUBTYPE_ARM_V7M +#undef CPU_SUBTYPE_ARM_V7EM + +#undef CPU_SUBTYPE_ARM64_ALL + +#undef CPU_SUBTYPE_SPARC_ALL + +#undef CPU_SUBTYPE_POWERPC +#undef CPU_SUBTYPE_POWERPC_ALL +#undef CPU_SUBTYPE_POWERPC_601 +#undef CPU_SUBTYPE_POWERPC_602 +#undef CPU_SUBTYPE_POWERPC_603 +#undef CPU_SUBTYPE_POWERPC_603e +#undef CPU_SUBTYPE_POWERPC_603ev +#undef CPU_SUBTYPE_POWERPC_604 +#undef CPU_SUBTYPE_POWERPC_604e +#undef CPU_SUBTYPE_POWERPC_620 +#undef CPU_SUBTYPE_POWERPC_750 +#undef CPU_SUBTYPE_POWERPC_7400 +#undef CPU_SUBTYPE_POWERPC_7450 +#undef CPU_SUBTYPE_POWERPC_970 + +#undef CPU_SUBTYPE_MC980000_ALL +#undef CPU_SUBTYPE_MC98601 + +#include "llvm/Support/MachO.h" + +#endif // liblldb_SafeMachO_h_ diff --git a/include/lldb/Utility/SharedCluster.h b/include/lldb/Utility/SharedCluster.h index 991af4b4fa49..3a34d8ddb415 100644 --- a/include/lldb/Utility/SharedCluster.h +++ b/include/lldb/Utility/SharedCluster.h @@ -13,6 +13,8 @@ #include "lldb/Utility/SharingPtr.h" #include "lldb/Host/Mutex.h" +#include "llvm/ADT/SmallPtrSet.h" + namespace lldb_private { namespace imp @@ -50,11 +52,12 @@ public: ~ClusterManager () { - size_t n_items = m_objects.size(); - for (size_t i = 0; i < n_items; i++) + for (typename llvm::SmallPtrSet::iterator pos = m_objects.begin(), end = m_objects.end(); pos != end; ++pos) { - delete m_objects[i]; + T *object = *pos; + delete object; } + // Decrement refcount should have been called on this ClusterManager, // and it should have locked the mutex, now we will unlock it before // we destroy it... @@ -64,8 +67,7 @@ public: void ManageObject (T *new_object) { Mutex::Locker locker (m_mutex); - if (!ContainsObject(new_object)) - m_objects.push_back (new_object); + m_objects.insert (new_object); } typename lldb_private::SharingPtr GetSharedPointer(T *desired_object) @@ -73,20 +75,13 @@ public: { Mutex::Locker locker (m_mutex); m_external_ref++; - assert (ContainsObject(desired_object)); + assert (m_objects.count(desired_object)); } return typename lldb_private::SharingPtr (desired_object, new imp::shared_ptr_refcount (this)); } private: - bool ContainsObject (const T *desired_object) - { - typename std::vector::iterator pos, end = m_objects.end(); - pos = std::find(m_objects.begin(), end, desired_object); - return pos != end; - } - void DecrementRefCount () { m_mutex.Lock(); @@ -99,7 +94,7 @@ private: friend class imp::shared_ptr_refcount; - std::vector m_objects; + llvm::SmallPtrSet m_objects; int m_external_ref; Mutex m_mutex; }; diff --git a/include/lldb/Utility/SharingPtr.h b/include/lldb/Utility/SharingPtr.h index c451ee6e3593..1b5f86bbe2df 100644 --- a/include/lldb/Utility/SharingPtr.h +++ b/include/lldb/Utility/SharingPtr.h @@ -15,7 +15,7 @@ // Microsoft Visual C++ currently does not enable std::atomic to work // in CLR mode - as such we need to "hack around it" for MSVC++ builds only -// using Windows specific instrinsics instead of the C++11 atomic support +// using Windows specific intrinsics instead of the C++11 atomic support #ifdef _MSC_VER #include #else @@ -69,8 +69,8 @@ public: private: virtual void on_zero_shared(); - // Outlaw copy constructor and assignment operator to keep effictive C++ - // warnings down to a minumum + // Outlaw copy constructor and assignment operator to keep effective C++ + // warnings down to a minimum shared_ptr_pointer (const shared_ptr_pointer &); shared_ptr_pointer & operator=(const shared_ptr_pointer &); }; @@ -138,6 +138,7 @@ private: struct nat {int for_bool_;}; public: SharingPtr(); + SharingPtr(std::nullptr_t); template explicit SharingPtr(Y* p); template explicit SharingPtr(Y* p, imp::shared_count *ctrl_block); template SharingPtr(const SharingPtr& r, element_type *p); @@ -191,6 +192,14 @@ SharingPtr::SharingPtr() cntrl_(0) { } + +template +inline +SharingPtr::SharingPtr(std::nullptr_t) +: ptr_(0), +cntrl_(0) +{ +} template template diff --git a/include/lldb/Utility/StringLexer.h b/include/lldb/Utility/StringLexer.h new file mode 100644 index 000000000000..42c169c5cf94 --- /dev/null +++ b/include/lldb/Utility/StringLexer.h @@ -0,0 +1,62 @@ +//===--------------------- StringLexer.h -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef utility_StringLexer_h_ +#define utility_StringLexer_h_ + +#include +#include + +namespace lldb_utility { + +class StringLexer +{ +public: + typedef std::string::size_type Position; + typedef std::string::size_type Size; + + typedef std::string::value_type Character; + + StringLexer (std::string s); + + StringLexer (const StringLexer& rhs); + + Character + Peek (); + + bool + NextIf (Character c); + + Character + Next (); + + bool + HasAtLeast (Size s); + + bool + HasAny (Character c); + + void + PutBack (Character c); + + StringLexer& + operator = (const StringLexer& rhs); + +private: + std::string m_data; + Position m_position; + std::list m_putback_data; + + void + Consume(); +}; + +} // namespace lldb_private + +#endif // #ifndef utility_StringLexer_h_ diff --git a/include/lldb/lldb-defines.h b/include/lldb/lldb-defines.h index 82307d2f5310..f8028c793233 100644 --- a/include/lldb/lldb-defines.h +++ b/include/lldb/lldb-defines.h @@ -12,6 +12,22 @@ #include "lldb/lldb-types.h" +#if defined (_WIN32) + #if defined(EXPORT_LIBLLDB) + #define LLDB_API __declspec(dllexport) + #elif defined(IMPORT_LIBLLDB) + #define LLDB_API __declspec(dllimport) + #else + #define LLDB_API + #endif +#else // defined (_MSC_VER) + #define LLDB_API +#endif + +#if !defined(INT32_MAX) + #define INT32_MAX 2147483647 +#endif + #if !defined(UINT32_MAX) #define UINT32_MAX 4294967295U #endif @@ -75,6 +91,7 @@ #define LLDB_INVALID_INDEX32 UINT32_MAX #define LLDB_INVALID_IVAR_OFFSET UINT32_MAX #define LLDB_INVALID_IMAGE_TOKEN UINT32_MAX +#define LLDB_INVALID_MODULE_VERSION UINT32_MAX #define LLDB_INVALID_REGNUM UINT32_MAX #define LLDB_INVALID_UID UINT64_MAX #define LLDB_INVALID_PROCESS_ID 0 @@ -86,7 +103,7 @@ #define LLDB_INVALID_QUEUE_ID 0 //---------------------------------------------------------------------- -/// CPU Type defintions +/// CPU Type definitions //---------------------------------------------------------------------- #define LLDB_ARCH_DEFAULT "systemArch" #define LLDB_ARCH_DEFAULT_32BIT "systemArch32" @@ -94,7 +111,7 @@ #define LLDB_INVALID_CPUTYPE (0xFFFFFFFEu) //---------------------------------------------------------------------- -/// Option Set defintions +/// Option Set definitions //---------------------------------------------------------------------- // FIXME: I'm sure there's some #define magic that can create all 32 sets on the // fly. That would have the added benefit of making this unreadable. @@ -112,7 +129,7 @@ #define LLDB_OPT_SET_10 (1U << 9) #define LLDB_OPT_SET_FROM_TO(A, B) (((1U << (B)) - 1) ^ (((1U << (A))-1) >> 1)) -#ifdef _WIN32 +#if defined (_WIN32) && !defined (MAX_PATH) #define MAX_PATH 260 #endif diff --git a/include/lldb/lldb-enumerations.h b/include/lldb/lldb-enumerations.h index 347e20f21df6..612487fd4fad 100644 --- a/include/lldb/lldb-enumerations.h +++ b/include/lldb/lldb-enumerations.h @@ -39,16 +39,18 @@ namespace lldb { typedef enum LaunchFlags { eLaunchFlagNone = 0u, - eLaunchFlagExec = (1u << 0), ///< Exec when launching and turn the calling process into a new process - eLaunchFlagDebug = (1u << 1), ///< Stop as soon as the process launches to allow the process to be debugged - eLaunchFlagStopAtEntry = (1u << 2), ///< Stop at the program entry point instead of auto-continuing when launching or attaching at entry point - eLaunchFlagDisableASLR = (1u << 3), ///< Disable Address Space Layout Randomization - eLaunchFlagDisableSTDIO = (1u << 4), ///< Disable stdio for inferior process (e.g. for a GUI app) - eLaunchFlagLaunchInTTY = (1u << 5), ///< Launch the process in a new TTY if supported by the host - eLaunchFlagLaunchInShell= (1u << 6), ///< Launch the process inside a shell to get shell expansion + eLaunchFlagExec = (1u << 0), ///< Exec when launching and turn the calling process into a new process + eLaunchFlagDebug = (1u << 1), ///< Stop as soon as the process launches to allow the process to be debugged + eLaunchFlagStopAtEntry = (1u << 2), ///< Stop at the program entry point instead of auto-continuing when launching or attaching at entry point + eLaunchFlagDisableASLR = (1u << 3), ///< Disable Address Space Layout Randomization + eLaunchFlagDisableSTDIO = (1u << 4), ///< Disable stdio for inferior process (e.g. for a GUI app) + eLaunchFlagLaunchInTTY = (1u << 5), ///< Launch the process in a new TTY if supported by the host + eLaunchFlagLaunchInShell= (1u << 6), ///< Launch the process inside a shell to get shell expansion eLaunchFlagLaunchInSeparateProcessGroup = (1u << 7), ///< Launch the process in a separate process group - eLaunchFlagsDontMonitorProcess = (1u << 8) ///< If you are going to hand the process off (e.g. to debugserver) - ///< set this flag so lldb & the handee don't race to reap it. + eLaunchFlagDontSetExitStatus = (1u << 8), ///< If you are going to hand the process off (e.g. to debugserver) + ///< set this flag so lldb & the handee don't race to set its exit status. + eLaunchFlagDetachOnError = (1u << 9) ///< If set, then the client stub should detach rather than killing the debugee + ///< if it loses connection with lldb. } LaunchFlags; //---------------------------------------------------------------------- @@ -155,13 +157,16 @@ namespace lldb { //---------------------------------------------------------------------- // Register numbering types + // See RegisterContext::ConvertRegisterKindToRegisterNumber to convert + // any of these to the lldb internal register numbering scheme + // (eRegisterKindLLDB). //---------------------------------------------------------------------- typedef enum RegisterKind { eRegisterKindGCC = 0, // the register numbers seen in eh_frame eRegisterKindDWARF, // the register numbers seen DWARF eRegisterKindGeneric, // insn ptr reg, stack ptr reg, etc not specific to any particular target - eRegisterKindGDB, // the register numbers gdb uses (matches stabs numbers?) + eRegisterKindGDB, // the register numbers gdb uses (matches stabs numbers) eRegisterKindLLDB, // lldb's internal register numbers kNumRegisterKinds } RegisterKind; @@ -199,6 +204,22 @@ namespace lldb { } ReturnStatus; + //---------------------------------------------------------------------- + // The results of expression evaluation: + //---------------------------------------------------------------------- + typedef enum ExpressionResults + { + eExpressionCompleted = 0, + eExpressionSetupError, + eExpressionParseError, + eExpressionDiscarded, + eExpressionInterrupted, + eExpressionHitBreakpoint, + eExpressionTimedOut, + eExpressionResultUnavailable, + eExpressionStoppedForDebug + } ExpressionResults; + //---------------------------------------------------------------------- // Connection Status Types //---------------------------------------------------------------------- @@ -209,7 +230,8 @@ namespace lldb { eConnectionStatusError, // Check GetError() for details eConnectionStatusTimedOut, // Request timed out eConnectionStatusNoConnection, // No connection - eConnectionStatusLostConnection // Lost connection while connected to a valid connection + eConnectionStatusLostConnection, // Lost connection while connected to a valid connection + eConnectionStatusInterrupted // Interrupted read } ConnectionStatus; typedef enum ErrorType @@ -217,7 +239,9 @@ namespace lldb { eErrorTypeInvalid, eErrorTypeGeneric, ///< Generic errors that can be any value. eErrorTypeMachKernel, ///< Mach kernel error codes. - eErrorTypePOSIX ///< POSIX error codes. + eErrorTypePOSIX, ///< POSIX error codes. + eErrorTypeExpression, ///< These are from the ExpressionResults enum. + eErrorTypeWin32 ///< Standard Win32 error codes. } ErrorType; @@ -349,6 +373,18 @@ namespace lldb { eLanguageTypeUPC = 0x0012, ///< Unified Parallel C. eLanguageTypeD = 0x0013, ///< D. eLanguageTypePython = 0x0014, ///< Python. + eLanguageTypeOpenCL = 0x0015, ///< OpenCL. + eLanguageTypeGo = 0x0016, ///< Go. + eLanguageTypeModula3 = 0x0017, ///< Modula 3. + eLanguageTypeHaskell = 0x0018, ///< Haskell. + eLanguageTypeC_plus_plus_03 = 0x0019, ///< ISO C++:2003. + eLanguageTypeC_plus_plus_11 = 0x001a, ///< ISO C++:2011. + eLanguageTypeOCaml = 0x001b, ///< OCaml. + eLanguageTypeRust = 0x001c, ///< Rust. + eLanguageTypeC11 = 0x001d, ///< ISO C:2011. + eLanguageTypeSwift = 0x001e, ///< Swift. + eLanguageTypeJulia = 0x001f, ///< Julia. + eLanguageTypeDylan = 0x0020, ///< Dylan. eNumLanguageTypes } LanguageType; @@ -653,14 +689,22 @@ namespace lldb { } TypeOptions; //---------------------------------------------------------------------- - // This is the return value for frame comparisons. When frame A pushes - // frame B onto the stack, frame A is OLDER than frame B. + // This is the return value for frame comparisons. If you are comparing frame A to frame B + // the following cases arise: + // 1) When frame A pushes frame B (or a frame that ends up pushing B) A is Older than B. + // 2) When frame A pushed frame B (or if frame A is on the stack but B is not) A is Younger than B + // 3) When frame A and frame B have the same StackID, they are Equal. + // 4) When frame A and frame B have the same immediate parent frame, but are not equal, the comparision yields + // SameParent. + // 5) If the two frames are on different threads or processes the comparision is Invalid + // 6) If for some reason we can't figure out what went on, we return Unknown. //---------------------------------------------------------------------- typedef enum FrameComparison { eFrameCompareInvalid, eFrameCompareUnknown, eFrameCompareEqual, + eFrameCompareSameParent, eFrameCompareYounger, eFrameCompareOlder } FrameComparison; @@ -741,6 +785,71 @@ namespace lldb { eQueueItemKindBlock } QueueItemKind; + //---------------------------------------------------------------------- + // Queue type + // libdispatch aka Grand Central Dispatch (GCD) queues can be either serial + // (executing on one thread) or concurrent (executing on multiple threads). + //---------------------------------------------------------------------- + typedef enum QueueKind + { + eQueueKindUnknown = 0, + eQueueKindSerial, + eQueueKindConcurrent + } QueueKind; + + //---------------------------------------------------------------------- + // Expression Evaluation Stages + // These are the cancellable stages of expression evaluation, passed to the + // expression evaluation callback, so that you can interrupt expression + // evaluation at the various points in its lifecycle. + //---------------------------------------------------------------------- + typedef enum ExpressionEvaluationPhase + { + eExpressionEvaluationParse = 0, + eExpressionEvaluationIRGen, + eExpressionEvaluationExecution, + eExpressionEvaluationComplete + } ExpressionEvaluationPhase; + + + //---------------------------------------------------------------------- + // Watchpoint Kind + // Indicates what types of events cause the watchpoint to fire. + // Used by Native*Protocol-related classes. + //---------------------------------------------------------------------- + typedef enum WatchpointKind + { + eWatchpointKindRead = (1u << 0), + eWatchpointKindWrite = (1u << 1) + } WatchpointKind; + + typedef enum GdbSignal + { + eGdbSignalBadAccess = 0x91, + eGdbSignalBadInstruction = 0x92, + eGdbSignalArithmetic = 0x93, + eGdbSignalEmulation = 0x94, + eGdbSignalSoftware = 0x95, + eGdbSignalBreakpoint = 0x96 + } GdbRemoteSignal; + + //---------------------------------------------------------------------- + // Used with SBHost::GetPath (lldb::PathType) to find files that are + // related to LLDB on the current host machine. Most files are relative + // to LLDB or are in known locations. + //---------------------------------------------------------------------- + typedef enum PathType + { + ePathTypeLLDBShlibDir, // The directory where the lldb.so (unix) or LLDB mach-o file in LLDB.framework (MacOSX) exists + ePathTypeSupportExecutableDir, // Find LLDB support executable directory (debugserver, etc) + ePathTypeHeaderDir, // Find LLDB header file directory + ePathTypePythonDir, // Find Python modules (PYTHONPATH) directory + ePathTypeLLDBSystemPlugins, // System plug-ins directory + ePathTypeLLDBUserPlugins, // User plug-ins directory + ePathTypeLLDBTempSystemDir // The LLDB temp directory for this system that will be cleaned up on exit + + } PathType; + } // namespace lldb diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h index 43e589e39521..b3d15224acb5 100644 --- a/include/lldb/lldb-forward.h +++ b/include/lldb/lldb-forward.h @@ -80,7 +80,6 @@ class Debugger; class Declaration; class Disassembler; struct DumpValueObjectOptions; -class DynamicLibrary; class DynamicLoader; class Editline; class EmulateInstruction; @@ -106,7 +105,9 @@ class InlineFunctionInfo; class Instruction; class InstructionList; class IOHandler; +class IOObject; class IRExecutionUnit; +class JITLoader; class LanguageRuntime; class SystemRuntime; class LineTable; @@ -127,6 +128,7 @@ class OptionGroup; class OptionGroupOptions; class OptionGroupPlatform; class ObjectFile; +class ObjectFileJITDelegate; class OperatingSystem; class Options; class OptionValue; @@ -242,9 +244,12 @@ class TypeImpl; class TypeList; class TypeListImpl; class TypeMemberImpl; +class TypeEnumMemberImpl; +class TypeEnumMemberListImpl; class TypeNameSpecifierImpl; class TypePair; class UUID; +class UnixSignals; class Unwind; class UnwindAssembly; class UnwindPlan; @@ -295,7 +300,6 @@ namespace lldb { typedef std::shared_ptr DebuggerSP; typedef std::weak_ptr DebuggerWP; typedef std::shared_ptr DisassemblerSP; - typedef std::shared_ptr DynamicLibrarySP; typedef std::shared_ptr DynamicLoaderSP; typedef std::shared_ptr EventSP; typedef std::shared_ptr ExecutionContextRefSP; @@ -305,6 +309,8 @@ namespace lldb { typedef std::shared_ptr InlineFunctionInfoSP; typedef std::shared_ptr InstructionSP; typedef std::shared_ptr IOHandlerSP; + typedef std::shared_ptr IOObjectSP; + typedef std::shared_ptr JITLoaderSP; typedef std::shared_ptr LanguageRuntimeSP; typedef std::shared_ptr SystemRuntimeSP; typedef std::shared_ptr LineTableSP; @@ -314,6 +320,8 @@ namespace lldb { typedef std::weak_ptr ModuleWP; typedef std::shared_ptr ObjectFileSP; typedef std::weak_ptr ObjectFileWP; + typedef std::shared_ptr ObjectFileJITDelegateSP; + typedef std::weak_ptr ObjectFileJITDelegateWP; typedef std::shared_ptr OptionValueSP; typedef std::weak_ptr OptionValueWP; typedef std::shared_ptr OptionValueArchSP; @@ -377,6 +385,7 @@ namespace lldb { typedef std::weak_ptr TypeWP; typedef std::shared_ptr TypeCategoryImplSP; typedef std::shared_ptr TypeImplSP; + typedef std::shared_ptr TypeEnumMemberImplSP; typedef std::shared_ptr TypeFilterImplSP; typedef std::shared_ptr TypeFormatImplSP; typedef std::shared_ptr TypeNameSpecifierImplSP; diff --git a/include/lldb/lldb-private-enumerations.h b/include/lldb/lldb-private-enumerations.h index c2273f5dfe2e..ee1589fe24ed 100644 --- a/include/lldb/lldb-private-enumerations.h +++ b/include/lldb/lldb-private-enumerations.h @@ -105,40 +105,6 @@ typedef enum SortOrder eSortOrderByName } SortOrder; - -//---------------------------------------------------------------------- -// Used in conjunction with Host::GetLLDBPath () to find files that -// are related to -//---------------------------------------------------------------------- -typedef enum PathType -{ - ePathTypeLLDBShlibDir, // The directory where the lldb.so (unix) or LLDB mach-o file in LLDB.framework (MacOSX) exists - ePathTypeSupportExecutableDir, // Find LLDB support executable directory (debugserver, etc) - ePathTypeHeaderDir, // Find LLDB header file directory - ePathTypePythonDir, // Find Python modules (PYTHONPATH) directory - ePathTypeLLDBSystemPlugins, // System plug-ins directory - ePathTypeLLDBUserPlugins, // User plug-ins directory - ePathTypeLLDBTempSystemDir // The LLDB temp directory for this system - -} PathType; - - -//---------------------------------------------------------------------- -// We can execute ThreadPlans on one thread with various fall-back modes -// (try other threads after timeout, etc.) This enum gives the result of -// thread plan executions. -//---------------------------------------------------------------------- -typedef enum ExecutionResults -{ - eExecutionSetupError, - eExecutionCompleted, - eExecutionDiscarded, - eExecutionInterrupted, - eExecutionHitBreakpoint, - eExecutionTimedOut, - eExecutionStoppedForDebug -} ExecutionResults; - typedef enum ObjCRuntimeVersions { eObjC_VersionUnknown = 0, eAppleObjC_V1 = 1, @@ -178,7 +144,7 @@ typedef enum NameMatchType typedef enum InstructionType { eInstructionTypeAny, // Support for any instructions at all (at least one) - eInstructionTypePrologueEpilogue, // All prologue and epilogue instructons that push and pop register values and modify sp/fp + eInstructionTypePrologueEpilogue, // All prologue and epilogue instructions that push and pop register values and modify sp/fp eInstructionTypePCModifying, // Any instruction that modifies the program counter/instruction pointer eInstructionTypeAll // All instructions of any kind @@ -262,6 +228,16 @@ enum class LineStatus { Done // Lines are complete }; +//---------------------------------------------------------------------- +// Exit Type for inferior processes +//---------------------------------------------------------------------- +typedef enum ExitType { + eExitTypeInvalid, + eExitTypeExit, // The exit status represents the return code from normal program exit (i.e. WIFEXITED() was true) + eExitTypeSignal, // The exit status represents the signal number that caused the program to exit (i.e. WIFSIGNALED() was true) + eExitTypeStop, // The exit status represents the stop signal that caused the program to exit (i.e. WIFSTOPPED() was true) +} ExitType; + } // namespace lldb_private diff --git a/include/lldb/lldb-private-forward.h b/include/lldb/lldb-private-forward.h new file mode 100644 index 000000000000..424aa4cc53f4 --- /dev/null +++ b/include/lldb/lldb-private-forward.h @@ -0,0 +1,41 @@ +//===-- lldb-private-forward.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_lldb_private_forward_h_ +#define LLDB_lldb_private_forward_h_ + +#if defined(__cplusplus) + +#include + +namespace lldb_private +{ + // --------------------------------------------------------------- + // Class forward decls. + // --------------------------------------------------------------- + class NativeBreakpoint; + class NativeBreakpointList; + class NativeProcessProtocol; + class NativeRegisterContext; + class NativeThreadProtocol; + class UnixSignals; + + // --------------------------------------------------------------- + // SP/WP decls. + // --------------------------------------------------------------- + typedef std::shared_ptr NativeBreakpointSP; + typedef std::shared_ptr NativeProcessProtocolSP; + typedef std::weak_ptr NativeProcessProtocolWP; + typedef std::shared_ptr NativeRegisterContextSP; + typedef std::shared_ptr NativeThreadProtocolSP; + typedef std::shared_ptr UnixSignalsSP; +} + +#endif // #if defined(__cplusplus) +#endif // #ifndef LLDB_lldb_private_forward_h_ diff --git a/include/lldb/lldb-private-interfaces.h b/include/lldb/lldb-private-interfaces.h index 5a2da8989f35..3251d6a9fe6c 100644 --- a/include/lldb/lldb-private-interfaces.h +++ b/include/lldb/lldb-private-interfaces.h @@ -19,10 +19,12 @@ namespace lldb_private typedef lldb::ABISP (*ABICreateInstance) (const ArchSpec &arch); typedef Disassembler* (*DisassemblerCreateInstance) (const ArchSpec &arch, const char *flavor); typedef DynamicLoader* (*DynamicLoaderCreateInstance) (Process* process, bool force); + typedef lldb::JITLoaderSP (*JITLoaderCreateInstance) (Process *process, bool force); typedef ObjectContainer* (*ObjectContainerCreateInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& data_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t offset, lldb::offset_t length); typedef size_t (*ObjectFileGetModuleSpecifications) (const FileSpec &file, lldb::DataBufferSP& data_sp, lldb::offset_t data_offset, lldb::offset_t file_offset, lldb::offset_t length, ModuleSpecList &module_specs); typedef ObjectFile* (*ObjectFileCreateInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& data_sp, lldb::offset_t data_offset, const FileSpec* file, lldb::offset_t file_offset, lldb::offset_t length); typedef ObjectFile* (*ObjectFileCreateMemoryInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t offset); + typedef bool (*ObjectFileSaveCore) (const lldb::ProcessSP &process_sp, const FileSpec &outfile, Error &error); typedef LogChannel* (*LogChannelCreateInstance) (); typedef EmulateInstruction * (*EmulateInstructionCreateInstance) (const ArchSpec &arch, InstructionType inst_type); typedef OperatingSystem* (*OperatingSystemCreateInstance) (Process *process, bool force); @@ -34,10 +36,10 @@ namespace lldb_private typedef SymbolVendor* (*SymbolVendorCreateInstance) (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm); // Module can be NULL for default system symbol vendor typedef bool (*BreakpointHitCallback) (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id); typedef bool (*WatchpointHitCallback) (void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id); - typedef lldb::ThreadPlanSP (*ThreadPlanShouldStopHereCallback) (ThreadPlan *current_plan, Flags &flags, void *baton); + typedef bool (*ThreadPlanShouldStopHereCallback) (ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, void *baton); + typedef lldb::ThreadPlanSP (*ThreadPlanStepFromHereCallback) (ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, void *baton); typedef UnwindAssembly* (*UnwindAssemblyCreateInstance) (const ArchSpec &arch); typedef int (*ComparisonFunction)(const void *, const void *); - typedef bool (*CommandOverrideCallback)(void *baton, const char **argv); typedef void (*DebuggerInitializeCallback)(Debugger &debugger); } // namespace lldb_private diff --git a/include/lldb/lldb-private-log.h b/include/lldb/lldb-private-log.h index 9d8d735dcf41..dc37ae2c7c42 100644 --- a/include/lldb/lldb-private-log.h +++ b/include/lldb/lldb-private-log.h @@ -46,6 +46,7 @@ #define LIBLLDB_LOG_OS (1u << 24) #define LIBLLDB_LOG_PLATFORM (1u << 25) #define LIBLLDB_LOG_SYSTEM_RUNTIME (1u << 26) +#define LIBLLDB_LOG_JIT_LOADER (1u << 27) #define LIBLLDB_LOG_ALL (UINT32_MAX) #define LIBLLDB_LOG_DEFAULT (LIBLLDB_LOG_PROCESS |\ LIBLLDB_LOG_THREAD |\ diff --git a/include/lldb/lldb-private-types.h b/include/lldb/lldb-private-types.h index 4340af114be3..12a9324008d8 100644 --- a/include/lldb/lldb-private-types.h +++ b/include/lldb/lldb-private-types.h @@ -16,6 +16,9 @@ namespace lldb_private { + class Platform; + class ExecutionContext; + //---------------------------------------------------------------------- // Every register is described in detail including its name, alternate // name (optional), encoding, size in bytes and the default display @@ -51,8 +54,16 @@ namespace lldb_private const char *string_value; const char *usage; } OptionEnumValueElement; + + struct OptionValidator + { + virtual ~OptionValidator() { } + virtual bool IsValid(Platform &platform, const ExecutionContext &target) const = 0; + virtual const char * ShortConditionString() const = 0; + virtual const char * LongConditionString() const = 0; + }; - typedef struct + struct OptionDefinition { uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0 // then this option belongs to option set n. @@ -60,12 +71,13 @@ namespace lldb_private const char *long_option; // Full name for this option. int short_option; // Single character for this option. int option_has_arg; // no_argument, required_argument or optional_argument + OptionValidator* validator; // If non-NULL, option is valid iff |validator->IsValid()|, otherwise always valid. OptionEnumValueElement *enum_values; // If non-NULL an array of enum values. uint32_t completion_type; // Cookie the option class can use to do define the argument completion. lldb::CommandArgumentType argument_type; // Type of argument this option takes const char *usage_text; // Full text explaining what this options does and what (if any) argument to // pass it. - } OptionDefinition; + }; } // namespace lldb_private diff --git a/include/lldb/lldb-python.h b/include/lldb/lldb-python.h index ce5c8176a3c3..c8ef054f60e1 100644 --- a/include/lldb/lldb-python.h +++ b/include/lldb/lldb-python.h @@ -13,13 +13,19 @@ // Python.h needs to be included before any system headers in order to avoid redefinition of macros #ifdef LLDB_DISABLE_PYTHON - // Python is disabled in this build - #else - -#include - + #if defined(__linux__) + // features.h will define _POSIX_C_SOURCE if _GNU_SOURCE is defined. This value + // may be different from the value that Python defines it to be which results + // in a warning. Undefine _POSIX_C_SOURCE before including Python.h The same + // holds for _XOPEN_SOURCE. + #undef _POSIX_C_SOURCE + #undef _XOPEN_SOURCE + #endif + + // Include python for non windows machines + #include #endif // LLDB_DISABLE_PYTHON #endif // LLDB_lldb_python_h_ diff --git a/include/lldb/lldb-types.h b/include/lldb/lldb-types.h index 5851b5d3f923..fee920f5b198 100644 --- a/include/lldb/lldb-types.h +++ b/include/lldb/lldb-types.h @@ -49,37 +49,46 @@ namespace lldb typedef void* mutex_t; typedef void* condition_t; typedef void* rwlock_t; + typedef void* process_t; // Process type is HANDLE typedef uintptr_t thread_t; // Host thread type typedef uint32_t thread_key_t; typedef void * thread_arg_t; // Host thread argument type typedef unsigned thread_result_t; // Host thread result type typedef thread_result_t (*thread_func_t)(void *); // Host thread function type - typedef void (*LogOutputCallback) (const char *, void *baton); - typedef bool (*CommandOverrideCallback)(void *baton, const char **argv); } #else #include -namespace lldb { - //---------------------------------------------------------------------- - // MacOSX Types - //---------------------------------------------------------------------- - typedef ::pthread_mutex_t mutex_t; - typedef pthread_cond_t condition_t; - typedef pthread_rwlock_t rwlock_t; - typedef pthread_t thread_t; // Host thread type - typedef pthread_key_t thread_key_t; - typedef void * thread_arg_t; // Host thread argument type - typedef void * thread_result_t; // Host thread result type - typedef void * (*thread_func_t)(void *); // Host thread function type - typedef void (*LogOutputCallback) (const char *, void *baton); - typedef bool (*CommandOverrideCallback)(void *baton, const char **argv); +namespace lldb +{ + //---------------------------------------------------------------------- + // MacOSX Types + //---------------------------------------------------------------------- + typedef ::pthread_mutex_t mutex_t; + typedef pthread_cond_t condition_t; + typedef pthread_rwlock_t rwlock_t; + typedef uint64_t process_t; // Process type is just a pid. + typedef pthread_t thread_t; // Host thread type + typedef pthread_key_t thread_key_t; + typedef void * thread_arg_t; // Host thread argument type + typedef void * thread_result_t; // Host thread result type + typedef void * (*thread_func_t)(void *); // Host thread function type } // namespace lldb #endif +namespace lldb +{ + typedef void (*LogOutputCallback) (const char *, void *baton); + typedef bool (*CommandOverrideCallback)(void *baton, const char **argv); + typedef bool (*CommandOverrideCallbackWithResult)(void *baton, + const char **argv, + lldb_private::CommandReturnObject &result); + typedef bool (*ExpressionCancelCallback) (ExpressionEvaluationPhase phase, void *baton); +} + #define LLDB_INVALID_HOST_THREAD ((lldb::thread_t)NULL) #define IS_VALID_LLDB_HOST_THREAD(t) ((t) != LLDB_INVALID_HOST_THREAD) diff --git a/source/API/SBAddress.cpp b/source/API/SBAddress.cpp index 799c90907634..6aec0722169f 100644 --- a/source/API/SBAddress.cpp +++ b/source/API/SBAddress.cpp @@ -127,13 +127,15 @@ SBAddress::GetLoadAddress (const SBTarget &target) const addr = m_opaque_ap->GetLoadAddress (target_sp.get()); } } - + if (log) { if (addr == LLDB_INVALID_ADDRESS) - log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => LLDB_INVALID_ADDRESS", target_sp.get()); + log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => LLDB_INVALID_ADDRESS", + static_cast(target_sp.get())); else - log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => 0x%" PRIx64, target_sp.get(), addr); + log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => 0x%" PRIx64, + static_cast(target_sp.get()), addr); } return addr; diff --git a/source/API/SBBreakpoint.cpp b/source/API/SBBreakpoint.cpp index fbdc0e32f498..a950ca934c68 100644 --- a/source/API/SBBreakpoint.cpp +++ b/source/API/SBBreakpoint.cpp @@ -19,9 +19,12 @@ #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/Address.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Log.h" #include "lldb/Core/Stream.h" #include "lldb/Core/StreamFile.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" @@ -121,9 +124,11 @@ SBBreakpoint::GetID () const if (log) { if (break_id == LLDB_INVALID_BREAK_ID) - log->Printf ("SBBreakpoint(%p)::GetID () => LLDB_INVALID_BREAK_ID", m_opaque_sp.get()); + log->Printf ("SBBreakpoint(%p)::GetID () => LLDB_INVALID_BREAK_ID", + static_cast(m_opaque_sp.get())); else - log->Printf ("SBBreakpoint(%p)::GetID () => %u", m_opaque_sp.get(), break_id); + log->Printf ("SBBreakpoint(%p)::GetID () => %u", + static_cast(m_opaque_sp.get()), break_id); } return break_id; @@ -133,7 +138,12 @@ SBBreakpoint::GetID () const bool SBBreakpoint::IsValid() const { - return (bool) m_opaque_sp; + if (!m_opaque_sp) + return false; + else if (m_opaque_sp->GetTarget().GetBreakpointByID(m_opaque_sp->GetID())) + return true; + else + return false; } void @@ -222,7 +232,8 @@ SBBreakpoint::SetEnabled (bool enable) Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBreakpoint(%p)::SetEnabled (enabled=%i)", m_opaque_sp.get(), enable); + log->Printf ("SBBreakpoint(%p)::SetEnabled (enabled=%i)", + static_cast(m_opaque_sp.get()), enable); if (m_opaque_sp) { @@ -249,7 +260,8 @@ SBBreakpoint::SetOneShot (bool one_shot) Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBreakpoint(%p)::SetOneShot (one_shot=%i)", m_opaque_sp.get(), one_shot); + log->Printf ("SBBreakpoint(%p)::SetOneShot (one_shot=%i)", + static_cast(m_opaque_sp.get()), one_shot); if (m_opaque_sp) { @@ -288,8 +300,9 @@ SBBreakpoint::SetIgnoreCount (uint32_t count) Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBreakpoint(%p)::SetIgnoreCount (count=%u)", m_opaque_sp.get(), count); - + log->Printf ("SBBreakpoint(%p)::SetIgnoreCount (count=%u)", + static_cast(m_opaque_sp.get()), count); + if (m_opaque_sp) { Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); @@ -330,7 +343,8 @@ SBBreakpoint::GetHitCount () const Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBreakpoint(%p)::GetHitCount () => %u", m_opaque_sp.get(), count); + log->Printf ("SBBreakpoint(%p)::GetHitCount () => %u", + static_cast(m_opaque_sp.get()), count); return count; } @@ -347,7 +361,8 @@ SBBreakpoint::GetIgnoreCount () const Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBreakpoint(%p)::GetIgnoreCount () => %u", m_opaque_sp.get(), count); + log->Printf ("SBBreakpoint(%p)::GetIgnoreCount () => %u", + static_cast(m_opaque_sp.get()), count); return count; } @@ -362,7 +377,8 @@ SBBreakpoint::SetThreadID (tid_t tid) } Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4" PRIx64 ")", m_opaque_sp.get(), tid); + log->Printf ("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4" PRIx64 ")", + static_cast(m_opaque_sp.get()), tid); } @@ -378,7 +394,8 @@ SBBreakpoint::GetThreadID () Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBreakpoint(%p)::GetThreadID () => 0x%4.4" PRIx64, m_opaque_sp.get(), tid); + log->Printf ("SBBreakpoint(%p)::GetThreadID () => 0x%4.4" PRIx64, + static_cast(m_opaque_sp.get()), tid); return tid; } @@ -387,7 +404,8 @@ SBBreakpoint::SetThreadIndex (uint32_t index) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBreakpoint(%p)::SetThreadIndex (%u)", m_opaque_sp.get(), index); + log->Printf ("SBBreakpoint(%p)::SetThreadIndex (%u)", + static_cast(m_opaque_sp.get()), index); if (m_opaque_sp) { Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); @@ -408,18 +426,19 @@ SBBreakpoint::GetThreadIndex() const } Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBreakpoint(%p)::GetThreadIndex () => %u", m_opaque_sp.get(), thread_idx); + log->Printf ("SBBreakpoint(%p)::GetThreadIndex () => %u", + static_cast(m_opaque_sp.get()), thread_idx); return thread_idx; } - void SBBreakpoint::SetThreadName (const char *thread_name) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBreakpoint(%p)::SetThreadName (%s)", m_opaque_sp.get(), thread_name); + log->Printf ("SBBreakpoint(%p)::SetThreadName (%s)", + static_cast(m_opaque_sp.get()), thread_name); if (m_opaque_sp) { @@ -441,7 +460,8 @@ SBBreakpoint::GetThreadName () const } Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBreakpoint(%p)::GetThreadName () => %s", m_opaque_sp.get(), name); + log->Printf ("SBBreakpoint(%p)::GetThreadName () => %s", + static_cast(m_opaque_sp.get()), name); return name; } @@ -451,7 +471,8 @@ SBBreakpoint::SetQueueName (const char *queue_name) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBreakpoint(%p)::SetQueueName (%s)", m_opaque_sp.get(), queue_name); + log->Printf ("SBBreakpoint(%p)::SetQueueName (%s)", + static_cast(m_opaque_sp.get()), queue_name); if (m_opaque_sp) { Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); @@ -472,7 +493,8 @@ SBBreakpoint::GetQueueName () const } Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBreakpoint(%p)::GetQueueName () => %s", m_opaque_sp.get(), name); + log->Printf ("SBBreakpoint(%p)::GetQueueName () => %s", + static_cast(m_opaque_sp.get()), name); return name; } @@ -488,7 +510,9 @@ SBBreakpoint::GetNumResolvedLocations() const } Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBreakpoint(%p)::GetNumResolvedLocations () => %" PRIu64, m_opaque_sp.get(), (uint64_t)num_resolved); + log->Printf ("SBBreakpoint(%p)::GetNumResolvedLocations () => %" PRIu64, + static_cast(m_opaque_sp.get()), + static_cast(num_resolved)); return num_resolved; } @@ -503,7 +527,9 @@ SBBreakpoint::GetNumLocations() const } Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBreakpoint(%p)::GetNumLocations () => %" PRIu64, m_opaque_sp.get(), (uint64_t)num_locs); + log->Printf ("SBBreakpoint(%p)::GetNumLocations () => %" PRIu64, + static_cast(m_opaque_sp.get()), + static_cast(num_locs)); return num_locs; } @@ -567,9 +593,14 @@ void SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + if (log) - log->Printf ("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)", m_opaque_sp.get(), callback, baton); + { + void *pointer = &callback; + log->Printf ("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)", + static_cast(m_opaque_sp.get()), + *static_cast(&pointer), static_cast(baton)); + } if (m_opaque_sp) { @@ -579,6 +610,48 @@ SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton) } } +void +SBBreakpoint::SetScriptCallbackFunction (const char *callback_function_name) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::SetScriptCallbackFunction (callback=%s)", + static_cast(m_opaque_sp.get()), + callback_function_name); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + BreakpointOptions *bp_options = m_opaque_sp->GetOptions(); + m_opaque_sp->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallbackFunction (bp_options, + callback_function_name); + } +} + +SBError +SBBreakpoint::SetScriptCallbackBody (const char *callback_body_text) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::SetScriptCallbackBody: callback body:\n%s)", + static_cast(m_opaque_sp.get()), callback_body_text); + + SBError sb_error; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + BreakpointOptions *bp_options = m_opaque_sp->GetOptions(); + Error error = m_opaque_sp->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options, + callback_body_text); + sb_error.SetError(error); + } + else + sb_error.SetErrorString("invalid breakpoint"); + + return sb_error; +} lldb_private::Breakpoint * SBBreakpoint::operator->() const diff --git a/source/API/SBBreakpointLocation.cpp b/source/API/SBBreakpointLocation.cpp index 6fdf59f38b4a..4390e9ad737a 100644 --- a/source/API/SBBreakpointLocation.cpp +++ b/source/API/SBBreakpointLocation.cpp @@ -17,10 +17,13 @@ #include "lldb/lldb-defines.h" #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointLocation.h" -#include "lldb/Target/ThreadSpec.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Log.h" #include "lldb/Core/Stream.h" #include "lldb/Core/StreamFile.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Target/ThreadSpec.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadSpec.h" @@ -43,7 +46,9 @@ SBBreakpointLocation::SBBreakpointLocation (const lldb::BreakpointLocationSP &br SBStream sstr; GetDescription (sstr, lldb::eDescriptionLevelBrief); log->Printf ("SBBreakpointLocation::SBBreakpointLocaiton (const lldb::BreakpointLocationsSP &break_loc_sp" - "=%p) => this.sp = %p (%s)", break_loc_sp.get(), m_opaque_sp.get(), sstr.GetData()); + "=%p) => this.sp = %p (%s)", + static_cast(break_loc_sp.get()), + static_cast(m_opaque_sp.get()), sstr.GetData()); } } @@ -159,6 +164,49 @@ SBBreakpointLocation::GetCondition () return NULL; } +void +SBBreakpointLocation::SetScriptCallbackFunction (const char *callback_function_name) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpointLocation(%p)::SetScriptCallbackFunction (callback=%s)", + static_cast(m_opaque_sp.get()), + callback_function_name); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + BreakpointOptions *bp_options = m_opaque_sp->GetLocationOptions(); + m_opaque_sp->GetBreakpoint().GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallbackFunction (bp_options, + callback_function_name); + } +} + +SBError +SBBreakpointLocation::SetScriptCallbackBody (const char *callback_body_text) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::SetScriptCallbackBody: callback body:\n%s)", + static_cast(m_opaque_sp.get()), callback_body_text); + + SBError sb_error; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + BreakpointOptions *bp_options = m_opaque_sp->GetLocationOptions(); + Error error = m_opaque_sp->GetBreakpoint().GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options, + callback_body_text); + sb_error.SetError(error); + } + else + sb_error.SetErrorString("invalid breakpoint"); + + return sb_error; +} + void SBBreakpointLocation::SetThreadID (tid_t thread_id) { @@ -312,8 +360,9 @@ SBBreakpointLocation::GetBreakpoint () { SBStream sstr; sb_bp.GetDescription (sstr); - log->Printf ("SBBreakpointLocation(%p)::GetBreakpoint () => SBBreakpoint(%p) %s", - m_opaque_sp.get(), sb_bp.get(), sstr.GetData()); + log->Printf ("SBBreakpointLocation(%p)::GetBreakpoint () => SBBreakpoint(%p) %s", + static_cast(m_opaque_sp.get()), + static_cast(sb_bp.get()), sstr.GetData()); } return sb_bp; } diff --git a/source/API/SBBroadcaster.cpp b/source/API/SBBroadcaster.cpp index 7168305ac80b..73eac5183f8a 100644 --- a/source/API/SBBroadcaster.cpp +++ b/source/API/SBBroadcaster.cpp @@ -33,7 +33,7 @@ SBBroadcaster::SBBroadcaster (const char *name) : if (log) log->Printf ("SBBroadcaster::SBBroadcaster (name=\"%s\") => SBBroadcaster(%p)", - name, m_opaque_ptr); + name, static_cast(m_opaque_ptr)); } SBBroadcaster::SBBroadcaster (lldb_private::Broadcaster *broadcaster, bool owns) : @@ -43,8 +43,9 @@ SBBroadcaster::SBBroadcaster (lldb_private::Broadcaster *broadcaster, bool owns) Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API | LIBLLDB_LOG_VERBOSE)); if (log) - log->Printf ("SBBroadcaster::SBBroadcaster (broadcaster=%p, bool owns=%i) => SBBroadcaster(%p)", - broadcaster, owns, m_opaque_ptr); + log->Printf ("SBBroadcaster::SBBroadcaster (broadcaster=%p, bool owns=%i) => SBBroadcaster(%p)", + static_cast(broadcaster), owns, + static_cast(m_opaque_ptr)); } SBBroadcaster::SBBroadcaster (const SBBroadcaster &rhs) : @@ -75,7 +76,8 @@ SBBroadcaster::BroadcastEventByType (uint32_t event_type, bool unique) Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBroadcaster(%p)::BroadcastEventByType (event_type=0x%8.8x, unique=%i)", m_opaque_ptr, event_type, unique); + log->Printf ("SBBroadcaster(%p)::BroadcastEventByType (event_type=0x%8.8x, unique=%i)", + static_cast(m_opaque_ptr), event_type, unique); if (m_opaque_ptr == NULL) return; @@ -92,7 +94,9 @@ SBBroadcaster::BroadcastEvent (const SBEvent &event, bool unique) Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBroadcaster(%p)::BroadcastEventByType (SBEvent(%p), unique=%i)", m_opaque_ptr, event.get(), unique); + log->Printf ("SBBroadcaster(%p)::BroadcastEventByType (SBEvent(%p), unique=%i)", + static_cast(m_opaque_ptr), + static_cast(event.get()), unique); if (m_opaque_ptr == NULL) return; @@ -109,7 +113,9 @@ SBBroadcaster::AddInitialEventsToListener (const SBListener &listener, uint32_t { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBBroadcaster(%p)::AddInitialEventsToListener (SBListener(%p), event_mask=0x%8.8x)", m_opaque_ptr, listener.get(), requested_events); + log->Printf ("SBBroadcaster(%p)::AddInitialEventsToListener (SBListener(%p), event_mask=0x%8.8x)", + static_cast(m_opaque_ptr), + static_cast(listener.get()), requested_events); if (m_opaque_ptr) m_opaque_ptr->AddInitialEventsToListener (listener.get(), requested_events); } diff --git a/source/API/SBCommandInterpreter.cpp b/source/API/SBCommandInterpreter.cpp index f1faa13ba981..e1adea795b08 100644 --- a/source/API/SBCommandInterpreter.cpp +++ b/source/API/SBCommandInterpreter.cpp @@ -65,7 +65,9 @@ SBCommandInterpreter::SBCommandInterpreter (CommandInterpreter *interpreter) : if (log) log->Printf ("SBCommandInterpreter::SBCommandInterpreter (interpreter=%p)" - " => SBCommandInterpreter(%p)", interpreter, m_opaque_ptr); + " => SBCommandInterpreter(%p)", + static_cast(interpreter), + static_cast(m_opaque_ptr)); } SBCommandInterpreter::SBCommandInterpreter(const SBCommandInterpreter &rhs) : @@ -129,12 +131,14 @@ SBCommandInterpreter::HandleCommand (const char *command_line, SBCommandReturnOb Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p), add_to_history=%i)", - m_opaque_ptr, command_line, result.get(), add_to_history); + log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p), add_to_history=%i)", + static_cast(m_opaque_ptr), command_line, + static_cast(result.get()), add_to_history); result.Clear(); if (command_line && m_opaque_ptr) { + result.ref().SetInteractive(false); m_opaque_ptr->HandleCommand (command_line, add_to_history ? eLazyBoolYes : eLazyBoolNo, result.ref()); } else @@ -150,7 +154,9 @@ SBCommandInterpreter::HandleCommand (const char *command_line, SBCommandReturnOb SBStream sstr; result.GetDescription (sstr); log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p): %s, add_to_history=%i) => %i", - m_opaque_ptr, command_line, result.get(), sstr.GetData(), add_to_history, result.GetStatus()); + static_cast(m_opaque_ptr), command_line, + static_cast(result.get()), sstr.GetData(), + add_to_history, result.GetStatus()); } return result.GetStatus(); @@ -166,23 +172,27 @@ SBCommandInterpreter::HandleCompletion (const char *current_line, { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); int num_completions = 0; - + // Sanity check the arguments that are passed in: // cursor & last_char have to be within the current_line. if (current_line == NULL || cursor == NULL || last_char == NULL) return 0; - + if (cursor < current_line || last_char < current_line) return 0; - + size_t current_line_size = strlen (current_line); - if (cursor - current_line > current_line_size || last_char - current_line > current_line_size) + if (cursor - current_line > static_cast(current_line_size) || + last_char - current_line > static_cast(current_line_size)) return 0; - + if (log) log->Printf ("SBCommandInterpreter(%p)::HandleCompletion (current_line=\"%s\", cursor at: %" PRId64 ", last char at: %" PRId64 ", match_start_point: %d, max_return_elements: %d)", - m_opaque_ptr, current_line, (uint64_t) (cursor - current_line), (uint64_t) (last_char - current_line), match_start_point, max_return_elements); - + static_cast(m_opaque_ptr), current_line, + static_cast(cursor - current_line), + static_cast(last_char - current_line), + match_start_point, max_return_elements); + if (m_opaque_ptr) { lldb_private::StringList lldb_matches; @@ -193,8 +203,9 @@ SBCommandInterpreter::HandleCompletion (const char *current_line, matches.AppendList (temp_list); } if (log) - log->Printf ("SBCommandInterpreter(%p)::HandleCompletion - Found %d completions.", m_opaque_ptr, num_completions); - + log->Printf ("SBCommandInterpreter(%p)::HandleCompletion - Found %d completions.", + static_cast(m_opaque_ptr), num_completions); + return num_completions; } @@ -253,9 +264,9 @@ SBCommandInterpreter::GetProcess () if (log) log->Printf ("SBCommandInterpreter(%p)::GetProcess () => SBProcess(%p)", - m_opaque_ptr, process_sp.get()); + static_cast(m_opaque_ptr), + static_cast(process_sp.get())); - return sb_process; } @@ -266,12 +277,12 @@ SBCommandInterpreter::GetDebugger () if (m_opaque_ptr) sb_debugger.reset(m_opaque_ptr->GetDebugger().shared_from_this()); Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + if (log) log->Printf ("SBCommandInterpreter(%p)::GetDebugger () => SBDebugger(%p)", - m_opaque_ptr, sb_debugger.get()); - - + static_cast(m_opaque_ptr), + static_cast(sb_debugger.get())); + return sb_debugger; } @@ -315,8 +326,8 @@ SBCommandInterpreter::SourceInitFileInHomeDirectory (SBCommandReturnObject &resu if (log) log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInHomeDirectory (&SBCommandReturnObject(%p))", - m_opaque_ptr, result.get()); - + static_cast(m_opaque_ptr), + static_cast(result.get())); } void @@ -340,7 +351,8 @@ SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory (SBCommandReturnOb if (log) log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInCurrentWorkingDirectory (&SBCommandReturnObject(%p))", - m_opaque_ptr, result.get()); + static_cast(m_opaque_ptr), + static_cast(result.get())); } SBBroadcaster @@ -352,7 +364,7 @@ SBCommandInterpreter::GetBroadcaster () if (log) log->Printf ("SBCommandInterpreter(%p)::GetBroadcaster() => SBBroadcaster(%p)", - m_opaque_ptr, broadcaster.get()); + static_cast(m_opaque_ptr), static_cast(broadcaster.get())); return broadcaster; } diff --git a/source/API/SBCommandReturnObject.cpp b/source/API/SBCommandReturnObject.cpp index 83d65637d3f2..1ae2df76c979 100644 --- a/source/API/SBCommandReturnObject.cpp +++ b/source/API/SBCommandReturnObject.cpp @@ -75,14 +75,16 @@ SBCommandReturnObject::GetOutput () if (m_opaque_ap.get()) { if (log) - log->Printf ("SBCommandReturnObject(%p)::GetOutput () => \"%s\"", m_opaque_ap.get(), + log->Printf ("SBCommandReturnObject(%p)::GetOutput () => \"%s\"", + static_cast(m_opaque_ap.get()), m_opaque_ap->GetOutputData()); return m_opaque_ap->GetOutputData(); } if (log) - log->Printf ("SBCommandReturnObject(%p)::GetOutput () => NULL", m_opaque_ap.get()); + log->Printf ("SBCommandReturnObject(%p)::GetOutput () => NULL", + static_cast(m_opaque_ap.get())); return NULL; } @@ -95,14 +97,16 @@ SBCommandReturnObject::GetError () if (m_opaque_ap.get()) { if (log) - log->Printf ("SBCommandReturnObject(%p)::GetError () => \"%s\"", m_opaque_ap.get(), + log->Printf ("SBCommandReturnObject(%p)::GetError () => \"%s\"", + static_cast(m_opaque_ap.get()), m_opaque_ap->GetErrorData()); return m_opaque_ap->GetErrorData(); } - + if (log) - log->Printf ("SBCommandReturnObject(%p)::GetError () => NULL", m_opaque_ap.get()); + log->Printf ("SBCommandReturnObject(%p)::GetError () => NULL", + static_cast(m_opaque_ap.get())); return NULL; } diff --git a/source/API/SBCommunication.cpp b/source/API/SBCommunication.cpp index 10feae5d4ebb..df0b864fad94 100644 --- a/source/API/SBCommunication.cpp +++ b/source/API/SBCommunication.cpp @@ -32,7 +32,8 @@ SBCommunication::SBCommunication(const char * broadcaster_name) : if (log) log->Printf ("SBCommunication::SBCommunication (broadcaster_name=\"%s\") => " - "SBCommunication(%p)", broadcaster_name, m_opaque); + "SBCommunication(%p)", broadcaster_name, + static_cast(m_opaque)); } SBCommunication::~SBCommunication() @@ -97,8 +98,9 @@ SBCommunication::AdoptFileDesriptor (int fd, bool owns_fd) } if (log) - log->Printf ("SBCommunication(%p)::AdoptFileDescriptor (fd=%d, ownd_fd=%i) => %s", - m_opaque, fd, owns_fd, Communication::ConnectionStatusAsCString (status)); + log->Printf ("SBCommunication(%p)::AdoptFileDescriptor (fd=%d, ownd_fd=%i) => %s", + static_cast(m_opaque), fd, owns_fd, + Communication::ConnectionStatusAsCString (status)); return status; } @@ -114,7 +116,8 @@ SBCommunication::Disconnect () status = m_opaque->Disconnect (); if (log) - log->Printf ("SBCommunication(%p)::Disconnect () => %s", m_opaque, + log->Printf ("SBCommunication(%p)::Disconnect () => %s", + static_cast(m_opaque), Communication::ConnectionStatusAsCString (status)); return status; @@ -129,7 +132,8 @@ SBCommunication::IsConnected () const result = m_opaque->IsConnected (); if (log) - log->Printf ("SBCommunication(%p)::IsConnected () => %i", m_opaque, result); + log->Printf ("SBCommunication(%p)::IsConnected () => %i", + static_cast(m_opaque), result); return false; } @@ -140,10 +144,8 @@ SBCommunication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, Connect Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBCommunication(%p)::Read (dst=%p, dst_len=%" PRIu64 ", timeout_usec=%u, &status)...", - m_opaque, - dst, - (uint64_t)dst_len, - timeout_usec); + static_cast(m_opaque), static_cast(dst), + static_cast(dst_len), timeout_usec); size_t bytes_read = 0; if (m_opaque) bytes_read = m_opaque->Read (dst, dst_len, timeout_usec, status, NULL); @@ -152,12 +154,10 @@ SBCommunication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, Connect if (log) log->Printf ("SBCommunication(%p)::Read (dst=%p, dst_len=%" PRIu64 ", timeout_usec=%u, &status=%s) => %" PRIu64, - m_opaque, - dst, - (uint64_t)dst_len, - timeout_usec, + static_cast(m_opaque), static_cast(dst), + static_cast(dst_len), timeout_usec, Communication::ConnectionStatusAsCString (status), - (uint64_t)bytes_read); + static_cast(bytes_read)); return bytes_read; } @@ -174,7 +174,10 @@ SBCommunication::Write (const void *src, size_t src_len, ConnectionStatus &statu Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBCommunication(%p)::Write (src=%p, src_len=%" PRIu64 ", &status=%s) => %" PRIu64, - m_opaque, src, (uint64_t)src_len, Communication::ConnectionStatusAsCString (status), (uint64_t)bytes_written); + static_cast(m_opaque), static_cast(src), + static_cast(src_len), + Communication::ConnectionStatusAsCString (status), + static_cast(bytes_written)); return 0; } @@ -189,7 +192,8 @@ SBCommunication::ReadThreadStart () success = m_opaque->StartReadThread (); if (log) - log->Printf ("SBCommunication(%p)::ReadThreadStart () => %i", m_opaque, success); + log->Printf ("SBCommunication(%p)::ReadThreadStart () => %i", + static_cast(m_opaque), success); return success; } @@ -200,14 +204,16 @@ SBCommunication::ReadThreadStop () { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBCommunication(%p)::ReadThreadStop ()...", m_opaque); + log->Printf ("SBCommunication(%p)::ReadThreadStop ()...", + static_cast(m_opaque)); bool success = false; if (m_opaque) success = m_opaque->StopReadThread (); if (log) - log->Printf ("SBCommunication(%p)::ReadThreadStop () => %i", m_opaque, success); + log->Printf ("SBCommunication(%p)::ReadThreadStop () => %i", + static_cast(m_opaque), success); return success; } @@ -220,7 +226,8 @@ SBCommunication::ReadThreadIsRunning () result = m_opaque->ReadThreadIsRunning (); Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBCommunication(%p)::ReadThreadIsRunning () => %i", m_opaque, result); + log->Printf ("SBCommunication(%p)::ReadThreadIsRunning () => %i", + static_cast(m_opaque), result); return result; } @@ -242,7 +249,9 @@ SBCommunication::SetReadThreadBytesReceivedCallback if (log) log->Printf ("SBCommunication(%p)::SetReadThreadBytesReceivedCallback (callback=%p, baton=%p) => %i", - m_opaque, callback, callback_baton, result); + static_cast(m_opaque), + reinterpret_cast(reinterpret_cast(callback)), + static_cast(callback_baton), result); return result; } @@ -256,7 +265,8 @@ SBCommunication::GetBroadcaster () if (log) log->Printf ("SBCommunication(%p)::GetBroadcaster () => SBBroadcaster (%p)", - m_opaque, broadcaster.get()); + static_cast(m_opaque), + static_cast(broadcaster.get())); return broadcaster; } diff --git a/source/API/SBCompileUnit.cpp b/source/API/SBCompileUnit.cpp index 9f7487746a85..03c25710a9e4 100644 --- a/source/API/SBCompileUnit.cpp +++ b/source/API/SBCompileUnit.cpp @@ -87,13 +87,14 @@ SBCompileUnit::GetLineEntryAtIndex (uint32_t idx) const sb_line_entry.SetLineEntry(line_entry); } } - + if (log) { SBStream sstr; sb_line_entry.GetDescription (sstr); - log->Printf ("SBCompileUnit(%p)::GetLineEntryAtIndex (idx=%u) => SBLineEntry(%p): '%s'", - m_opaque_ptr, idx, sb_line_entry.get(), sstr.GetData()); + log->Printf ("SBCompileUnit(%p)::GetLineEntryAtIndex (idx=%u) => SBLineEntry(%p): '%s'", + static_cast(m_opaque_ptr), idx, + static_cast(sb_line_entry.get()), sstr.GetData()); } return sb_line_entry; @@ -120,7 +121,6 @@ SBCompileUnit::FindLineEntryIndex (uint32_t start_idx, uint32_t line, SBFileSpec else file_spec = *m_opaque_ptr; - index = m_opaque_ptr->FindLineEntry (start_idx, line, inline_file_spec ? inline_file_spec->get() : NULL, @@ -133,13 +133,20 @@ SBCompileUnit::FindLineEntryIndex (uint32_t start_idx, uint32_t line, SBFileSpec SBStream sstr; if (index == UINT32_MAX) { - log->Printf ("SBCompileUnit(%p)::FindLineEntryIndex (start_idx=%u, line=%u, SBFileSpec(%p)) => NOT FOUND", - m_opaque_ptr, start_idx, line, inline_file_spec ? inline_file_spec->get() : NULL); + log->Printf ("SBCompileUnit(%p)::FindLineEntryIndex (start_idx=%u, line=%u, SBFileSpec(%p)) => NOT FOUND", + static_cast(m_opaque_ptr), start_idx, line, + inline_file_spec + ? static_cast(inline_file_spec->get()) + : NULL); } else { - log->Printf ("SBCompileUnit(%p)::FindLineEntryIndex (start_idx=%u, line=%u, SBFileSpec(%p)) => %u", - m_opaque_ptr, start_idx, line, inline_file_spec ? inline_file_spec->get() : NULL, index); + log->Printf ("SBCompileUnit(%p)::FindLineEntryIndex (start_idx=%u, line=%u, SBFileSpec(%p)) => %u", + static_cast(m_opaque_ptr), start_idx, line, + inline_file_spec + ? static_cast(inline_file_spec->get()) + : NULL, + index); } } @@ -196,13 +203,15 @@ SBCompileUnit::GetSupportFileAtIndex (uint32_t idx) const FileSpec file_spec = support_files.GetFileSpecAtIndex(idx); sb_file_spec.SetFileSpec(file_spec); } - + if (log) { SBStream sstr; sb_file_spec.GetDescription (sstr); - log->Printf ("SBCompileUnit(%p)::GetGetFileSpecAtIndex (idx=%u) => SBFileSpec(%p): '%s'", - m_opaque_ptr, idx, sb_file_spec.get(), sstr.GetData()); + log->Printf ("SBCompileUnit(%p)::GetGetFileSpecAtIndex (idx=%u) => SBFileSpec(%p): '%s'", + static_cast(m_opaque_ptr), idx, + static_cast(sb_file_spec.get()), + sstr.GetData()); } return sb_file_spec; diff --git a/source/API/SBData.cpp b/source/API/SBData.cpp index 06dcfc12af41..a58585295a21 100644 --- a/source/API/SBData.cpp +++ b/source/API/SBData.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +#include // PRIu64 + #include "lldb/API/SBData.h" #include "lldb/API/SBError.h" #include "lldb/API/SBStream.h" @@ -122,7 +124,7 @@ SBData::GetByteSize () value = m_opaque_sp->GetByteSize(); if (log) log->Printf ("SBData::GetByteSize () => " - "(%zu)", value); + "( %" PRIu64 " )", (uint64_t)value); return value; } @@ -167,8 +169,8 @@ SBData::GetFloat (lldb::SBError& error, lldb::offset_t offset) error.SetErrorString("unable to read data"); } if (log) - log->Printf ("SBData::GetFloat (error=%p,offset=%" PRIu64 ") => " - "(%f)", error.get(), offset, value); + log->Printf ("SBData::GetFloat (error=%p,offset=%" PRIu64 ") => (%f)", + static_cast(error.get()), offset, value); return value; } @@ -190,7 +192,7 @@ SBData::GetDouble (lldb::SBError& error, lldb::offset_t offset) } if (log) log->Printf ("SBData::GetDouble (error=%p,offset=%" PRIu64 ") => " - "(%f)", error.get(), offset, value); + "(%f)", static_cast(error.get()), offset, value); return value; } @@ -212,7 +214,7 @@ SBData::GetLongDouble (lldb::SBError& error, lldb::offset_t offset) } if (log) log->Printf ("SBData::GetLongDouble (error=%p,offset=%" PRIu64 ") => " - "(%Lf)", error.get(), offset, value); + "(%Lf)", static_cast(error.get()), offset, value); return value; } @@ -234,7 +236,8 @@ SBData::GetAddress (lldb::SBError& error, lldb::offset_t offset) } if (log) log->Printf ("SBData::GetAddress (error=%p,offset=%" PRIu64 ") => " - "(%p)", error.get(), offset, (void*)value); + "(%p)", static_cast(error.get()), offset, + reinterpret_cast(value)); return value; } @@ -256,7 +259,7 @@ SBData::GetUnsignedInt8 (lldb::SBError& error, lldb::offset_t offset) } if (log) log->Printf ("SBData::GetUnsignedInt8 (error=%p,offset=%" PRIu64 ") => " - "(%c)", error.get(), offset, value); + "(%c)", static_cast(error.get()), offset, value); return value; } @@ -278,7 +281,7 @@ SBData::GetUnsignedInt16 (lldb::SBError& error, lldb::offset_t offset) } if (log) log->Printf ("SBData::GetUnsignedInt16 (error=%p,offset=%" PRIu64 ") => " - "(%hd)", error.get(), offset, value); + "(%hd)", static_cast(error.get()), offset, value); return value; } @@ -300,7 +303,7 @@ SBData::GetUnsignedInt32 (lldb::SBError& error, lldb::offset_t offset) } if (log) log->Printf ("SBData::GetUnsignedInt32 (error=%p,offset=%" PRIu64 ") => " - "(%d)", error.get(), offset, value); + "(%d)", static_cast(error.get()), offset, value); return value; } @@ -322,7 +325,8 @@ SBData::GetUnsignedInt64 (lldb::SBError& error, lldb::offset_t offset) } if (log) log->Printf ("SBData::GetUnsignedInt64 (error=%p,offset=%" PRIu64 ") => " - "(%" PRId64 ")", error.get(), offset, value); + "(%" PRId64 ")", static_cast(error.get()), offset, + value); return value; } @@ -344,7 +348,7 @@ SBData::GetSignedInt8 (lldb::SBError& error, lldb::offset_t offset) } if (log) log->Printf ("SBData::GetSignedInt8 (error=%p,offset=%" PRIu64 ") => " - "(%c)", error.get(), offset, value); + "(%c)", static_cast(error.get()), offset, value); return value; } @@ -366,7 +370,7 @@ SBData::GetSignedInt16 (lldb::SBError& error, lldb::offset_t offset) } if (log) log->Printf ("SBData::GetSignedInt16 (error=%p,offset=%" PRIu64 ") => " - "(%hd)", error.get(), offset, value); + "(%hd)", static_cast(error.get()), offset, value); return value; } @@ -388,7 +392,7 @@ SBData::GetSignedInt32 (lldb::SBError& error, lldb::offset_t offset) } if (log) log->Printf ("SBData::GetSignedInt32 (error=%p,offset=%" PRIu64 ") => " - "(%d)", error.get(), offset, value); + "(%d)", static_cast(error.get()), offset, value); return value; } @@ -410,7 +414,8 @@ SBData::GetSignedInt64 (lldb::SBError& error, lldb::offset_t offset) } if (log) log->Printf ("SBData::GetSignedInt64 (error=%p,offset=%" PRIu64 ") => " - "(%" PRId64 ")", error.get(), offset, value); + "(%" PRId64 ")", static_cast(error.get()), offset, + value); return value; } @@ -431,8 +436,9 @@ SBData::GetString (lldb::SBError& error, lldb::offset_t offset) error.SetErrorString("unable to read data"); } if (log) - log->Printf ("SBData::GetString (error=%p,offset=%" PRIu64 ") => " - "(%p)", error.get(), offset, value); + log->Printf ("SBData::GetString (error=%p,offset=%" PRIu64 ") => (%p)", + static_cast(error.get()), offset, + static_cast(value)); return value; } @@ -479,8 +485,10 @@ SBData::ReadRawData (lldb::SBError& error, error.SetErrorString("unable to read data"); } if (log) - log->Printf ("SBData::ReadRawData (error=%p,offset=%" PRIu64 ",buf=%p,size=%zu) => " - "(%p)", error.get(), offset, buf, size, ok); + log->Printf("SBData::ReadRawData (error=%p,offset=%" PRIu64 ",buf=%p,size=%" PRIu64 ") => " + "(%p)", static_cast(error.get()), offset, + static_cast(buf), static_cast(size), + static_cast(ok)); return ok ? size : 0; } @@ -497,8 +505,10 @@ SBData::SetData (lldb::SBError& error, else m_opaque_sp->SetData(buf, size, endian); if (log) - log->Printf ("SBData::SetData (error=%p,buf=%p,size=%zu,endian=%d,addr_size=%c) => " - "(%p)", error.get(), buf, size, endian, addr_size, m_opaque_sp.get()); + log->Printf("SBData::SetData (error=%p,buf=%p,size=%" PRIu64 ",endian=%d,addr_size=%c) => " + "(%p)", static_cast(error.get()), + static_cast(buf), static_cast(size), + endian, addr_size, static_cast(m_opaque_sp.get())); } bool @@ -509,8 +519,8 @@ SBData::Append (const SBData& rhs) if (m_opaque_sp.get() && rhs.m_opaque_sp.get()) value = m_opaque_sp.get()->Append(*rhs.m_opaque_sp); if (log) - log->Printf ("SBData::Append (rhs=%p) => " - "(%s)", rhs.get(), value ? "true" : "false"); + log->Printf ("SBData::Append (rhs=%p) => (%s)", + static_cast(rhs.get()), value ? "true" : "false"); return value; } @@ -614,28 +624,28 @@ bool SBData::SetDataFromCString (const char* data) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + if (!data) { if (log) - log->Printf ("SBData::SetDataFromCString (data=%p) => " - "false", data); + log->Printf ("SBData::SetDataFromCString (data=%p) => false", + static_cast(data)); return false; } - + size_t data_len = strlen(data); - + lldb::DataBufferSP buffer_sp(new DataBufferHeap(data, data_len)); - + if (!m_opaque_sp.get()) m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize())); else m_opaque_sp->SetData(buffer_sp); - + if (log) - log->Printf ("SBData::SetDataFromCString (data=%p) => " - "true", data); - + log->Printf ("SBData::SetDataFromCString (data=%p) => true", + static_cast(data)); + return true; } @@ -643,28 +653,30 @@ bool SBData::SetDataFromUInt64Array (uint64_t* array, size_t array_len) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + if (!array || array_len == 0) { if (log) - log->Printf ("SBData::SetDataFromUInt64Array (array=%p, array_len = %zu) => " - "false", array, array_len); + log->Printf("SBData::SetDataFromUInt64Array (array=%p, array_len = %" PRIu64 ") => " + "false", static_cast(array), + static_cast(array_len)); return false; } size_t data_len = array_len * sizeof(uint64_t); - + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); - + if (!m_opaque_sp.get()) m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize())); else m_opaque_sp->SetData(buffer_sp); - + if (log) - log->Printf ("SBData::SetDataFromUInt64Array (array=%p, array_len = %zu) => " - "true", array, array_len); - + log->Printf("SBData::SetDataFromUInt64Array (array=%p, array_len = %" PRIu64 ") => " + "true", static_cast(array), + static_cast(array_len)); + return true; } @@ -672,28 +684,30 @@ bool SBData::SetDataFromUInt32Array (uint32_t* array, size_t array_len) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + if (!array || array_len == 0) { if (log) - log->Printf ("SBData::SetDataFromUInt32Array (array=%p, array_len = %zu) => " - "false", array, array_len); + log->Printf("SBData::SetDataFromUInt32Array (array=%p, array_len = %" PRIu64 ") => " + "false", static_cast(array), + static_cast(array_len)); return false; } - + size_t data_len = array_len * sizeof(uint32_t); - + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); - + if (!m_opaque_sp.get()) m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize())); else m_opaque_sp->SetData(buffer_sp); - + if (log) - log->Printf ("SBData::SetDataFromUInt32Array (array=%p, array_len = %zu) => " - "true", array, array_len); - + log->Printf("SBData::SetDataFromUInt32Array (array=%p, array_len = %" PRIu64 ") => " + "true", static_cast(array), + static_cast(array_len)); + return true; } @@ -701,28 +715,30 @@ bool SBData::SetDataFromSInt64Array (int64_t* array, size_t array_len) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + if (!array || array_len == 0) { if (log) - log->Printf ("SBData::SetDataFromSInt64Array (array=%p, array_len = %zu) => " - "false", array, array_len); + log->Printf("SBData::SetDataFromSInt64Array (array=%p, array_len = %" PRIu64 ") => " + "false", static_cast(array), + static_cast(array_len)); return false; } - + size_t data_len = array_len * sizeof(int64_t); - + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); - + if (!m_opaque_sp.get()) m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize())); else m_opaque_sp->SetData(buffer_sp); - + if (log) - log->Printf ("SBData::SetDataFromSInt64Array (array=%p, array_len = %zu) => " - "true", array, array_len); - + log->Printf("SBData::SetDataFromSInt64Array (array=%p, array_len = %" PRIu64 ") => " + "true", static_cast(array), + static_cast(array_len)); + return true; } @@ -730,28 +746,30 @@ bool SBData::SetDataFromSInt32Array (int32_t* array, size_t array_len) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + if (!array || array_len == 0) { if (log) - log->Printf ("SBData::SetDataFromSInt32Array (array=%p, array_len = %zu) => " - "false", array, array_len); + log->Printf("SBData::SetDataFromSInt32Array (array=%p, array_len = %" PRIu64 ") => " + "false", static_cast(array), + static_cast(array_len)); return false; } - + size_t data_len = array_len * sizeof(int32_t); - + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); - + if (!m_opaque_sp.get()) m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize())); else m_opaque_sp->SetData(buffer_sp); - + if (log) - log->Printf ("SBData::SetDataFromSInt32Array (array=%p, array_len = %zu) => " - "true", array, array_len); - + log->Printf("SBData::SetDataFromSInt32Array (array=%p, array_len = %" PRIu64 ") => " + "true", static_cast(array), + static_cast(array_len)); + return true; } @@ -759,27 +777,29 @@ bool SBData::SetDataFromDoubleArray (double* array, size_t array_len) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + if (!array || array_len == 0) { if (log) - log->Printf ("SBData::SetDataFromDoubleArray (array=%p, array_len = %zu) => " - "false", array, array_len); + log->Printf("SBData::SetDataFromDoubleArray (array=%p, array_len = %" PRIu64 ") => " + "false", static_cast(array), + static_cast(array_len)); return false; } - + size_t data_len = array_len * sizeof(double); - + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); - + if (!m_opaque_sp.get()) m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize())); else m_opaque_sp->SetData(buffer_sp); - + if (log) - log->Printf ("SBData::SetDataFromDoubleArray (array=%p, array_len = %zu) => " - "true", array, array_len); - + log->Printf("SBData::SetDataFromDoubleArray (array=%p, array_len = %" PRIu64 ") => " + "true", static_cast(array), + static_cast(array_len)); + return true; } diff --git a/source/API/SBDebugger.cpp b/source/API/SBDebugger.cpp index 8d6887a6c280..dae567525a4a 100644 --- a/source/API/SBDebugger.cpp +++ b/source/API/SBDebugger.cpp @@ -38,13 +38,14 @@ #include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/DataFormatters/DataVisualization.h" -#include "lldb/Host/DynamicLibrary.h" #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/OptionGroupPlatform.h" #include "lldb/Target/Process.h" #include "lldb/Target/TargetList.h" +#include "llvm/Support/DynamicLibrary.h" + using namespace lldb; using namespace lldb_private; @@ -72,22 +73,22 @@ SBInputReader::IsActive() const return false; } -static lldb::DynamicLibrarySP +static llvm::sys::DynamicLibrary LoadPlugin (const lldb::DebuggerSP &debugger_sp, const FileSpec& spec, Error& error) { - lldb::DynamicLibrarySP dynlib_sp(new lldb_private::DynamicLibrary(spec)); - if (dynlib_sp && dynlib_sp->IsValid()) + llvm::sys::DynamicLibrary dynlib = llvm::sys::DynamicLibrary::getPermanentLibrary(spec.GetPath().c_str()); + if (dynlib.isValid()) { typedef bool (*LLDBCommandPluginInit) (lldb::SBDebugger& debugger); lldb::SBDebugger debugger_sb(debugger_sp); // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger) function. // TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays - LLDBCommandPluginInit init_func = dynlib_sp->GetSymbol("_ZN4lldb16PluginInitializeENS_10SBDebuggerE"); + LLDBCommandPluginInit init_func = (LLDBCommandPluginInit)dynlib.getAddressOfSymbol("_ZN4lldb16PluginInitializeENS_10SBDebuggerE"); if (init_func) { if (init_func(debugger_sb)) - return dynlib_sp; + return dynlib; else error.SetErrorString("plug-in refused to load (lldb::PluginInitialize(lldb::SBDebugger) returned false)"); } @@ -103,7 +104,7 @@ LoadPlugin (const lldb::DebuggerSP &debugger_sp, const FileSpec& spec, Error& er else error.SetErrorString("no such file"); } - return lldb::DynamicLibrarySP(); + return llvm::sys::DynamicLibrary(); } void @@ -131,8 +132,9 @@ SBDebugger::Clear () Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBDebugger(%p)::Clear ()", m_opaque_sp.get()); - + log->Printf ("SBDebugger(%p)::Clear ()", + static_cast(m_opaque_sp.get())); + if (m_opaque_sp) m_opaque_sp->ClearIOHandlers (); @@ -158,13 +160,24 @@ SBDebugger::Create(bool source_init_files, lldb::LogOutputCallback callback, voi Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBDebugger debugger; + + // Currently we have issues if this function is called simultaneously on two different + // threads. The issues mainly revolve around the fact that the lldb_private::FormatManager + // uses global collections and having two threads parsing the .lldbinit files can cause + // mayhem. So to get around this for now we need to use a mutex to prevent bad things + // from happening. + static Mutex g_mutex(Mutex::eMutexTypeRecursive); + Mutex::Locker locker(g_mutex); + debugger.reset(Debugger::CreateInstance(callback, baton)); if (log) { SBStream sstr; debugger.GetDescription (sstr); - log->Printf ("SBDebugger::Create () => SBDebugger(%p): %s", debugger.m_opaque_sp.get(), sstr.GetData()); + log->Printf ("SBDebugger::Create () => SBDebugger(%p): %s", + static_cast(debugger.m_opaque_sp.get()), + sstr.GetData()); } SBCommandInterpreter interp = debugger.GetCommandInterpreter(); @@ -187,16 +200,18 @@ void SBDebugger::Destroy (SBDebugger &debugger) { Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + if (log) { SBStream sstr; debugger.GetDescription (sstr); - log->Printf ("SBDebugger::Destroy () => SBDebugger(%p): %s", debugger.m_opaque_sp.get(), sstr.GetData()); + log->Printf ("SBDebugger::Destroy () => SBDebugger(%p): %s", + static_cast(debugger.m_opaque_sp.get()), + sstr.GetData()); } - + Debugger::Destroy (debugger.m_opaque_sp); - + if (debugger.m_opaque_sp.get() != NULL) debugger.m_opaque_sp.reset(); } @@ -293,8 +308,9 @@ SBDebugger::SetInputFileHandle (FILE *fh, bool transfer_ownership) Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBDebugger(%p)::SetInputFileHandle (fh=%p, transfer_ownership=%i)", m_opaque_sp.get(), - fh, transfer_ownership); + log->Printf ("SBDebugger(%p)::SetInputFileHandle (fh=%p, transfer_ownership=%i)", + static_cast(m_opaque_sp.get()), + static_cast(fh), transfer_ownership); if (m_opaque_sp) m_opaque_sp->SetInputFileHandle (fh, transfer_ownership); @@ -307,8 +323,9 @@ SBDebugger::SetOutputFileHandle (FILE *fh, bool transfer_ownership) if (log) - log->Printf ("SBDebugger(%p)::SetOutputFileHandle (fh=%p, transfer_ownership=%i)", m_opaque_sp.get(), - fh, transfer_ownership); + log->Printf ("SBDebugger(%p)::SetOutputFileHandle (fh=%p, transfer_ownership=%i)", + static_cast(m_opaque_sp.get()), + static_cast(fh), transfer_ownership); if (m_opaque_sp) m_opaque_sp->SetOutputFileHandle (fh, transfer_ownership); @@ -321,8 +338,9 @@ SBDebugger::SetErrorFileHandle (FILE *fh, bool transfer_ownership) if (log) - log->Printf ("SBDebugger(%p)::SetErrorFileHandle (fh=%p, transfer_ownership=%i)", m_opaque_sp.get(), - fh, transfer_ownership); + log->Printf ("SBDebugger(%p)::SetErrorFileHandle (fh=%p, transfer_ownership=%i)", + static_cast(m_opaque_sp.get()), + static_cast(fh), transfer_ownership); if (m_opaque_sp) m_opaque_sp->SetErrorFileHandle (fh, transfer_ownership); @@ -389,8 +407,9 @@ SBDebugger::GetCommandInterpreter () sb_interpreter.reset (&m_opaque_sp->GetCommandInterpreter()); if (log) - log->Printf ("SBDebugger(%p)::GetCommandInterpreter () => SBCommandInterpreter(%p)", - m_opaque_sp.get(), sb_interpreter.get()); + log->Printf ("SBDebugger(%p)::GetCommandInterpreter () => SBCommandInterpreter(%p)", + static_cast(m_opaque_sp.get()), + static_cast(sb_interpreter.get())); return sb_interpreter; } @@ -443,8 +462,9 @@ SBDebugger::GetListener () sb_listener.reset(&m_opaque_sp->GetListener(), false); if (log) - log->Printf ("SBDebugger(%p)::GetListener () => SBListener(%p)", m_opaque_sp.get(), - sb_listener.get()); + log->Printf ("SBDebugger(%p)::GetListener () => SBListener(%p)", + static_cast(m_opaque_sp.get()), + static_cast(sb_listener.get())); return sb_listener; } @@ -601,14 +621,14 @@ SBDebugger::CreateTarget (const char *filename, sb_error.Clear(); OptionGroupPlatform platform_options (false); platform_options.SetPlatformName (platform_name); - + sb_error.ref() = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, filename, target_triple, add_dependent_modules, &platform_options, target_sp); - + if (sb_error.Success()) sb_target.SetSP (target_sp); } @@ -616,20 +636,14 @@ SBDebugger::CreateTarget (const char *filename, { sb_error.SetErrorString("invalid target"); } - + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - { - log->Printf ("SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, platform_name=%s, add_dependent_modules=%u, error=%s) => SBTarget(%p)", - m_opaque_sp.get(), - filename, - target_triple, - platform_name, - add_dependent_modules, - sb_error.GetCString(), - target_sp.get()); - } - + log->Printf ("SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, platform_name=%s, add_dependent_modules=%u, error=%s) => SBTarget(%p)", + static_cast(m_opaque_sp.get()), filename, + target_triple, platform_name, add_dependent_modules, + sb_error.GetCString(), static_cast(target_sp.get())); + return sb_target; } @@ -650,13 +664,12 @@ SBDebugger::CreateTargetWithFileAndTargetTriple (const char *filename, target_sp)); sb_target.SetSP (target_sp); } - + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - { - log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndTargetTriple (filename=\"%s\", triple=%s) => SBTarget(%p)", - m_opaque_sp.get(), filename, target_triple, target_sp.get()); - } + log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndTargetTriple (filename=\"%s\", triple=%s) => SBTarget(%p)", + static_cast(m_opaque_sp.get()), filename, + target_triple, static_cast(target_sp.get())); return sb_target; } @@ -688,10 +701,9 @@ SBDebugger::CreateTargetWithFileAndArch (const char *filename, const char *arch_ } if (log) - { - log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", arch=%s) => SBTarget(%p)", - m_opaque_sp.get(), filename, arch_cstr, target_sp.get()); - } + log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", arch=%s) => SBTarget(%p)", + static_cast(m_opaque_sp.get()), filename, arch_cstr, + static_cast(target_sp.get())); return sb_target; } @@ -723,10 +735,9 @@ SBDebugger::CreateTarget (const char *filename) } Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - { - log->Printf ("SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)", - m_opaque_sp.get(), filename, target_sp.get()); - } + log->Printf ("SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)", + static_cast(m_opaque_sp.get()), filename, + static_cast(target_sp.get())); return sb_target; } @@ -750,9 +761,9 @@ SBDebugger::DeleteTarget (lldb::SBTarget &target) Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - { - log->Printf ("SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i", m_opaque_sp.get(), target.m_opaque_sp.get(), result); - } + log->Printf ("SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i", + static_cast(m_opaque_sp.get()), + static_cast(target.m_opaque_sp.get()), result); return result; } @@ -850,8 +861,9 @@ SBDebugger::GetSelectedTarget () { SBStream sstr; sb_target.GetDescription (sstr, eDescriptionLevelBrief); - log->Printf ("SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s", m_opaque_sp.get(), - target_sp.get(), sstr.GetData()); + log->Printf ("SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s", + static_cast(m_opaque_sp.get()), + static_cast(target_sp.get()), sstr.GetData()); } return sb_target; @@ -871,8 +883,9 @@ SBDebugger::SetSelectedTarget (SBTarget &sb_target) { SBStream sstr; sb_target.GetDescription (sstr, eDescriptionLevelBrief); - log->Printf ("SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s", m_opaque_sp.get(), - target_sp.get(), sstr.GetData()); + log->Printf ("SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s", + static_cast(m_opaque_sp.get()), + static_cast(target_sp.get()), sstr.GetData()); } } @@ -888,10 +901,10 @@ SBDebugger::GetSelectedPlatform() sb_platform.SetSP(debugger_sp->GetPlatformList().GetSelectedPlatform()); } if (log) - { - log->Printf ("SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s", m_opaque_sp.get(), - sb_platform.GetSP().get(), sb_platform.GetName()); - } + log->Printf ("SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s", + static_cast(m_opaque_sp.get()), + static_cast(sb_platform.GetSP().get()), + sb_platform.GetName()); return sb_platform; } @@ -899,17 +912,18 @@ void SBDebugger::SetSelectedPlatform(SBPlatform &sb_platform) { Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + DebuggerSP debugger_sp(m_opaque_sp); if (debugger_sp) { debugger_sp->GetPlatformList().SetSelectedPlatform(sb_platform.GetSP()); } + if (log) - { - log->Printf ("SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)", m_opaque_sp.get(), - sb_platform.GetSP().get(), sb_platform.GetName()); - } + log->Printf ("SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)", + static_cast(m_opaque_sp.get()), + static_cast(sb_platform.GetSP().get()), + sb_platform.GetName()); } void @@ -1077,9 +1091,10 @@ const char * SBDebugger::GetPrompt() const { Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + if (log) - log->Printf ("SBDebugger(%p)::GetPrompt () => \"%s\"", m_opaque_sp.get(), + log->Printf ("SBDebugger(%p)::GetPrompt () => \"%s\"", + static_cast(m_opaque_sp.get()), (m_opaque_sp ? m_opaque_sp->GetPrompt() : "")); if (m_opaque_sp) diff --git a/source/API/SBDeclaration.cpp b/source/API/SBDeclaration.cpp index fc90156e75ad..8aea675afeba 100644 --- a/source/API/SBDeclaration.cpp +++ b/source/API/SBDeclaration.cpp @@ -74,19 +74,21 @@ SBFileSpec SBDeclaration::GetFileSpec () const { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + SBFileSpec sb_file_spec; if (m_opaque_ap.get() && m_opaque_ap->GetFile()) sb_file_spec.SetFileSpec(m_opaque_ap->GetFile()); - + if (log) { SBStream sstr; sb_file_spec.GetDescription (sstr); - log->Printf ("SBLineEntry(%p)::GetFileSpec () => SBFileSpec(%p): %s", m_opaque_ap.get(), - sb_file_spec.get(), sstr.GetData()); + log->Printf ("SBLineEntry(%p)::GetFileSpec () => SBFileSpec(%p): %s", + static_cast(m_opaque_ap.get()), + static_cast(sb_file_spec.get()), + sstr.GetData()); } - + return sb_file_spec; } @@ -94,14 +96,15 @@ uint32_t SBDeclaration::GetLine () const { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + uint32_t line = 0; if (m_opaque_ap.get()) line = m_opaque_ap->GetLine(); - + if (log) - log->Printf ("SBLineEntry(%p)::GetLine () => %u", m_opaque_ap.get(), line); - + log->Printf ("SBLineEntry(%p)::GetLine () => %u", + static_cast(m_opaque_ap.get()), line); + return line; } diff --git a/source/API/SBError.cpp b/source/API/SBError.cpp index bd6b54300f60..157997b2502f 100644 --- a/source/API/SBError.cpp +++ b/source/API/SBError.cpp @@ -77,7 +77,8 @@ SBError::Fail () const ret_value = m_opaque_ap->Fail(); if (log) - log->Printf ("SBError(%p)::Fail () => %i", m_opaque_ap.get(), ret_value); + log->Printf ("SBError(%p)::Fail () => %i", + static_cast(m_opaque_ap.get()), ret_value); return ret_value; } @@ -91,7 +92,8 @@ SBError::Success () const ret_value = m_opaque_ap->Success(); if (log) - log->Printf ("SBError(%p)::Success () => %i", m_opaque_ap.get(), ret_value); + log->Printf ("SBError(%p)::Success () => %i", + static_cast(m_opaque_ap.get()), ret_value); return ret_value; } @@ -106,7 +108,8 @@ SBError::GetError () const err = m_opaque_ap->GetError(); if (log) - log->Printf ("SBError(%p)::GetError () => 0x%8.8x", m_opaque_ap.get(), err); + log->Printf ("SBError(%p)::GetError () => 0x%8.8x", + static_cast(m_opaque_ap.get()), err); return err; @@ -121,7 +124,8 @@ SBError::GetType () const err_type = m_opaque_ap->GetType(); if (log) - log->Printf ("SBError(%p)::GetType () => %i", m_opaque_ap.get(), err_type); + log->Printf ("SBError(%p)::GetType () => %i", + static_cast(m_opaque_ap.get()), err_type); return err_type; } diff --git a/source/API/SBEvent.cpp b/source/API/SBEvent.cpp index d5d4a84bc1fd..57a699fd739d 100644 --- a/source/API/SBEvent.cpp +++ b/source/API/SBEvent.cpp @@ -92,9 +92,11 @@ SBEvent::GetType () const { StreamString sstr; if (lldb_event && lldb_event->GetBroadcaster() && lldb_event->GetBroadcaster()->GetEventNames(sstr, event_type, true)) - log->Printf ("SBEvent(%p)::GetType () => 0x%8.8x (%s)", get(), event_type, sstr.GetData()); + log->Printf ("SBEvent(%p)::GetType () => 0x%8.8x (%s)", + static_cast(get()), event_type, sstr.GetData()); else - log->Printf ("SBEvent(%p)::GetType () => 0x%8.8x", get(), event_type); + log->Printf ("SBEvent(%p)::GetType () => 0x%8.8x", + static_cast(get()), event_type); } @@ -141,11 +143,10 @@ SBEvent::BroadcasterMatchesRef (const SBBroadcaster &broadcaster) // For logging, this gets a little chatty so only enable this when verbose logging is on Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API | LIBLLDB_LOG_VERBOSE)); if (log) - log->Printf ("SBEvent(%p)::BroadcasterMatchesRef (SBBroadcaster(%p): %s) => %i", - get(), - broadcaster.get(), - broadcaster.GetName(), - success); + log->Printf ("SBEvent(%p)::BroadcasterMatchesRef (SBBroadcaster(%p): %s) => %i", + static_cast(get()), + static_cast(broadcaster.get()), + broadcaster.GetName(), success); return success; } @@ -206,8 +207,8 @@ SBEvent::GetCStringFromEvent (const SBEvent &event) Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBEvent(%p)::GetCStringFromEvent () => \"%s\"", - event.get(), + log->Printf ("SBEvent(%p)::GetCStringFromEvent () => \"%s\"", + static_cast(event.get()), reinterpret_cast(EventDataBytes::GetBytesFromEvent (event.get()))); return reinterpret_cast(EventDataBytes::GetBytesFromEvent (event.get())); diff --git a/source/API/SBExpressionOptions.cpp b/source/API/SBExpressionOptions.cpp index ae1c8f99df30..448ff4cf6dd6 100644 --- a/source/API/SBExpressionOptions.cpp +++ b/source/API/SBExpressionOptions.cpp @@ -101,6 +101,18 @@ SBExpressionOptions::SetTimeoutInMicroSeconds (uint32_t timeout) m_opaque_ap->SetTimeoutUsec (timeout); } +uint32_t +SBExpressionOptions::GetOneThreadTimeoutInMicroSeconds () const +{ + return m_opaque_ap->GetOneThreadTimeoutUsec (); +} + +void +SBExpressionOptions::SetOneThreadTimeoutInMicroSeconds (uint32_t timeout) +{ + m_opaque_ap->SetOneThreadTimeoutUsec (timeout); +} + bool SBExpressionOptions::GetTryAllThreads () const { @@ -113,6 +125,18 @@ SBExpressionOptions::SetTryAllThreads (bool run_others) m_opaque_ap->SetTryAllThreads (run_others); } +bool +SBExpressionOptions::GetStopOthers () const +{ + return m_opaque_ap->GetStopOthers (); +} + +void +SBExpressionOptions::SetStopOthers (bool run_others) +{ + m_opaque_ap->SetStopOthers (run_others); +} + bool SBExpressionOptions::GetTrapExceptions () const { @@ -125,6 +149,43 @@ SBExpressionOptions::SetTrapExceptions (bool trap_exceptions) m_opaque_ap->SetTrapExceptions (trap_exceptions); } +void +SBExpressionOptions::SetLanguage (lldb::LanguageType language) +{ + m_opaque_ap->SetLanguage(language); +} + +void +SBExpressionOptions::SetCancelCallback (lldb::ExpressionCancelCallback callback, void *baton) +{ + m_opaque_ap->SetCancelCallback (callback, baton); +} + +bool +SBExpressionOptions::GetGenerateDebugInfo () +{ + return m_opaque_ap->GetGenerateDebugInfo(); +} + +void +SBExpressionOptions::SetGenerateDebugInfo (bool b) +{ + return m_opaque_ap->SetGenerateDebugInfo(b); +} + +bool +SBExpressionOptions::GetSuppressPersistentResult () +{ + return m_opaque_ap->GetResultIsInternal (); +} + +void +SBExpressionOptions::SetSuppressPersistentResult (bool b) +{ + return m_opaque_ap->SetResultIsInternal (b); +} + + EvaluateExpressionOptions * SBExpressionOptions::get() const { diff --git a/source/API/SBFileSpec.cpp b/source/API/SBFileSpec.cpp index 4fd2866c9b05..8d63fc587d81 100644 --- a/source/API/SBFileSpec.cpp +++ b/source/API/SBFileSpec.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include // PRIu64 #include #include "lldb/API/SBFileSpec.h" @@ -15,6 +16,8 @@ #include "lldb/Core/Log.h" #include "lldb/Core/Stream.h" +#include "llvm/ADT/SmallString.h" + using namespace lldb; using namespace lldb_private; @@ -35,7 +38,7 @@ SBFileSpec::SBFileSpec (const lldb_private::FileSpec& fspec) : { } -// Deprected!!! +// Deprecated!!! SBFileSpec::SBFileSpec (const char *path) : m_opaque_ap(new FileSpec (path, true)) { @@ -72,7 +75,9 @@ SBFileSpec::Exists () const bool result = m_opaque_ap->Exists(); if (log) - log->Printf ("SBFileSpec(%p)::Exists () => %s", m_opaque_ap.get(), (result ? "true" : "false")); + log->Printf ("SBFileSpec(%p)::Exists () => %s", + static_cast(m_opaque_ap.get()), + (result ? "true" : "false")); return result; } @@ -86,7 +91,11 @@ SBFileSpec::ResolveExecutableLocation () int SBFileSpec::ResolvePath (const char *src_path, char *dst_path, size_t dst_len) { - return lldb_private::FileSpec::Resolve (src_path, dst_path, dst_len); + llvm::SmallString<64> result(src_path); + lldb_private::FileSpec::Resolve (result); + size_t result_length = std::min(dst_len-1, result.size()); + ::strncpy(dst_path, result.c_str(), result_length + 1); + return result_length; } const char * @@ -98,9 +107,11 @@ SBFileSpec::GetFilename() const if (log) { if (s) - log->Printf ("SBFileSpec(%p)::GetFilename () => \"%s\"", m_opaque_ap.get(), s); + log->Printf ("SBFileSpec(%p)::GetFilename () => \"%s\"", + static_cast(m_opaque_ap.get()), s); else - log->Printf ("SBFileSpec(%p)::GetFilename () => NULL", m_opaque_ap.get()); + log->Printf ("SBFileSpec(%p)::GetFilename () => NULL", + static_cast(m_opaque_ap.get())); } return s; @@ -114,9 +125,11 @@ SBFileSpec::GetDirectory() const if (log) { if (s) - log->Printf ("SBFileSpec(%p)::GetDirectory () => \"%s\"", m_opaque_ap.get(), s); + log->Printf ("SBFileSpec(%p)::GetDirectory () => \"%s\"", + static_cast(m_opaque_ap.get()), s); else - log->Printf ("SBFileSpec(%p)::GetDirectory () => NULL", m_opaque_ap.get()); + log->Printf ("SBFileSpec(%p)::GetDirectory () => NULL", + static_cast(m_opaque_ap.get())); } return s; } @@ -148,7 +161,8 @@ SBFileSpec::GetPath (char *dst_path, size_t dst_len) const if (log) log->Printf ("SBFileSpec(%p)::GetPath (dst_path=\"%.*s\", dst_len=%" PRIu64 ") => %u", - m_opaque_ap.get(), result, dst_path, (uint64_t)dst_len, result); + static_cast(m_opaque_ap.get()), result, dst_path, + static_cast(dst_len), result); if (result == 0 && dst_path && dst_len > 0) *dst_path = '\0'; diff --git a/source/API/SBFileSpecList.cpp b/source/API/SBFileSpecList.cpp index 3ebf3cc80a2a..a457a754f0d0 100644 --- a/source/API/SBFileSpecList.cpp +++ b/source/API/SBFileSpecList.cpp @@ -38,7 +38,8 @@ SBFileSpecList::SBFileSpecList (const SBFileSpecList &rhs) : if (log) { log->Printf ("SBFileSpecList::SBFileSpecList (const SBFileSpecList rhs.ap=%p) => SBFileSpecList(%p)", - rhs.m_opaque_ap.get(), m_opaque_ap.get()); + static_cast(rhs.m_opaque_ap.get()), + static_cast(m_opaque_ap.get())); } } diff --git a/source/API/SBFrame.cpp b/source/API/SBFrame.cpp index 44fc654c44b6..325f40fd5b56 100644 --- a/source/API/SBFrame.cpp +++ b/source/API/SBFrame.cpp @@ -63,9 +63,9 @@ SBFrame::SBFrame (const StackFrameSP &lldb_object_sp) : { SBStream sstr; GetDescription (sstr); - log->Printf ("SBFrame::SBFrame (sp=%p) => SBFrame(%p): %s", - lldb_object_sp.get(), lldb_object_sp.get(), sstr.GetData()); - + log->Printf ("SBFrame::SBFrame (sp=%p) => SBFrame(%p): %s", + static_cast(lldb_object_sp.get()), + static_cast(lldb_object_sp.get()), sstr.GetData()); } } @@ -141,8 +141,9 @@ SBFrame::GetSymbolContext (uint32_t resolve_scope) const } if (log) - log->Printf ("SBFrame(%p)::GetSymbolContext (resolve_scope=0x%8.8x) => SBSymbolContext(%p)", - frame, resolve_scope, sb_sym_ctx.get()); + log->Printf ("SBFrame(%p)::GetSymbolContext (resolve_scope=0x%8.8x) => SBSymbolContext(%p)", + static_cast(frame), resolve_scope, + static_cast(sb_sym_ctx.get())); return sb_sym_ctx; } @@ -184,8 +185,9 @@ SBFrame::GetModule () const } if (log) - log->Printf ("SBFrame(%p)::GetModule () => SBModule(%p)", - frame, module_sp.get()); + log->Printf ("SBFrame(%p)::GetModule () => SBModule(%p)", + static_cast(frame), + static_cast(module_sp.get())); return sb_module; } @@ -224,8 +226,9 @@ SBFrame::GetCompileUnit () const } } if (log) - log->Printf ("SBFrame(%p)::GetCompileUnit () => SBCompileUnit(%p)", - frame, sb_comp_unit.get()); + log->Printf ("SBFrame(%p)::GetCompileUnit () => SBCompileUnit(%p)", + static_cast(frame), + static_cast(sb_comp_unit.get())); return sb_comp_unit; } @@ -264,8 +267,9 @@ SBFrame::GetFunction () const } } if (log) - log->Printf ("SBFrame(%p)::GetFunction () => SBFunction(%p)", - frame, sb_function.get()); + log->Printf ("SBFrame(%p)::GetFunction () => SBFunction(%p)", + static_cast(frame), + static_cast(sb_function.get())); return sb_function; } @@ -304,8 +308,9 @@ SBFrame::GetSymbol () const } } if (log) - log->Printf ("SBFrame(%p)::GetSymbol () => SBSymbol(%p)", - frame, sb_symbol.get()); + log->Printf ("SBFrame(%p)::GetSymbol () => SBSymbol(%p)", + static_cast(frame), + static_cast(sb_symbol.get())); return sb_symbol; } @@ -339,12 +344,14 @@ SBFrame::GetBlock () const else { if (log) - log->Printf ("SBFrame(%p)::GetBlock () => error: process is running", frame); + log->Printf ("SBFrame(%p)::GetBlock () => error: process is running", + static_cast(frame)); } } if (log) - log->Printf ("SBFrame(%p)::GetBlock () => SBBlock(%p)", - frame, sb_block.GetPtr()); + log->Printf ("SBFrame(%p)::GetBlock () => SBBlock(%p)", + static_cast(frame), + static_cast(sb_block.GetPtr())); return sb_block; } @@ -382,8 +389,9 @@ SBFrame::GetFrameBlock () const } } if (log) - log->Printf ("SBFrame(%p)::GetFrameBlock () => SBBlock(%p)", - frame, sb_block.GetPtr()); + log->Printf ("SBFrame(%p)::GetFrameBlock () => SBBlock(%p)", + static_cast(frame), + static_cast(sb_block.GetPtr())); return sb_block; } @@ -421,8 +429,9 @@ SBFrame::GetLineEntry () const } } if (log) - log->Printf ("SBFrame(%p)::GetLineEntry () => SBLineEntry(%p)", - frame, sb_line_entry.get()); + log->Printf ("SBFrame(%p)::GetLineEntry () => SBLineEntry(%p)", + static_cast(frame), + static_cast(sb_line_entry.get())); return sb_line_entry; } @@ -430,16 +439,16 @@ uint32_t SBFrame::GetFrameID () const { uint32_t frame_idx = UINT32_MAX; - + ExecutionContext exe_ctx(m_opaque_sp.get()); StackFrame *frame = exe_ctx.GetFramePtr(); if (frame) frame_idx = frame->GetFrameIndex (); - + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBFrame(%p)::GetFrameID () => %u", - frame, frame_idx); + log->Printf ("SBFrame(%p)::GetFrameID () => %u", + static_cast(frame), frame_idx); return frame_idx; } @@ -478,7 +487,8 @@ SBFrame::GetPC () const } if (log) - log->Printf ("SBFrame(%p)::GetPC () => 0x%" PRIx64, frame, addr); + log->Printf ("SBFrame(%p)::GetPC () => 0x%" PRIx64, + static_cast(frame), addr); return addr; } @@ -519,7 +529,7 @@ SBFrame::SetPC (addr_t new_pc) if (log) log->Printf ("SBFrame(%p)::SetPC (new_pc=0x%" PRIx64 ") => %i", - frame, new_pc, ret_val); + static_cast(frame), new_pc, ret_val); return ret_val; } @@ -558,7 +568,8 @@ SBFrame::GetSP () const } } if (log) - log->Printf ("SBFrame(%p)::GetSP () => 0x%" PRIx64, frame, addr); + log->Printf ("SBFrame(%p)::GetSP () => 0x%" PRIx64, + static_cast(frame), addr); return addr; } @@ -599,7 +610,8 @@ SBFrame::GetFP () const } if (log) - log->Printf ("SBFrame(%p)::GetFP () => 0x%" PRIx64, frame, addr); + log->Printf ("SBFrame(%p)::GetFP () => 0x%" PRIx64, + static_cast(frame), addr); return addr; } @@ -638,7 +650,9 @@ SBFrame::GetPCAddress () const } } if (log) - log->Printf ("SBFrame(%p)::GetPCAddress () => SBAddress(%p)", frame, sb_addr.get()); + log->Printf ("SBFrame(%p)::GetPCAddress () => SBAddress(%p)", + static_cast(frame), + static_cast(sb_addr.get())); return sb_addr; } @@ -727,7 +741,6 @@ SBFrame::FindVariable (const char *name) } return value; } - SBValue SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic) @@ -742,7 +755,7 @@ SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic) log->Printf ("SBFrame::FindVariable called with empty name"); return sb_value; } - + ValueObjectSP value_sp; Mutex::Locker api_locker; ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); @@ -766,7 +779,7 @@ SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic) const bool can_create = true; const bool get_parent_variables = true; const bool stop_if_block_is_inlined_function = true; - + if (sc.block->AppendVariables (can_create, get_parent_variables, stop_if_block_is_inlined_function, @@ -794,10 +807,11 @@ SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic) log->Printf ("SBFrame::FindVariable () => error: process is running"); } } - + if (log) - log->Printf ("SBFrame(%p)::FindVariable (name=\"%s\") => SBValue(%p)", - frame, name, value_sp.get()); + log->Printf ("SBFrame(%p)::FindVariable (name=\"%s\") => SBValue(%p)", + static_cast(frame), name, + static_cast(value_sp.get())); return sb_value; } @@ -822,14 +836,14 @@ SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueTy { Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBValue sb_value; - + if (name == NULL || name[0] == '\0') { if (log) log->Printf ("SBFrame::FindValue called with empty name."); return sb_value; } - + ValueObjectSP value_sp; Mutex::Locker api_locker; ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); @@ -846,7 +860,7 @@ SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueTy if (frame) { VariableList variable_list; - + switch (value_type) { case eValueTypeVariableGlobal: // global variable @@ -854,7 +868,6 @@ SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueTy case eValueTypeVariableArgument: // function argument variables case eValueTypeVariableLocal: // function local variables { - SymbolContext sc (frame->GetSymbolContext (eSymbolContextBlock)); const bool can_create = true; @@ -957,12 +970,12 @@ SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueTy log->Printf ("SBFrame::FindValue () => error: process is running"); } } - + if (log) - log->Printf ("SBFrame(%p)::FindVariableInScope (name=\"%s\", value_type=%i) => SBValue(%p)", - frame, name, value_type, value_sp.get()); + log->Printf ("SBFrame(%p)::FindVariableInScope (name=\"%s\", value_type=%i) => SBValue(%p)", + static_cast(frame), name, value_type, + static_cast(value_sp.get())); - return sb_value; } @@ -999,10 +1012,9 @@ SBFrame::GetThread () const { SBStream sstr; sb_thread.GetDescription (sstr); - log->Printf ("SBFrame(%p)::GetThread () => SBThread(%p): %s", - exe_ctx.GetFramePtr(), - thread_sp.get(), - sstr.GetData()); + log->Printf ("SBFrame(%p)::GetThread () => SBThread(%p): %s", + static_cast(exe_ctx.GetFramePtr()), + static_cast(thread_sp.get()), sstr.GetData()); } return sb_thread; @@ -1039,11 +1051,12 @@ SBFrame::Disassemble () const { if (log) log->Printf ("SBFrame::Disassemble () => error: process is running"); - } + } } if (log) - log->Printf ("SBFrame(%p)::Disassemble () => %s", frame, disassembly); + log->Printf ("SBFrame(%p)::Disassemble () => %s", + static_cast(frame), disassembly); return disassembly; } @@ -1084,12 +1097,9 @@ SBFrame::GetVariables (bool arguments, Target *target = exe_ctx.GetTargetPtr(); if (log) - log->Printf ("SBFrame::GetVariables (arguments=%i, locals=%i, statics=%i, in_scope_only=%i)", - arguments, - locals, - statics, - in_scope_only); - + log->Printf ("SBFrame::GetVariables (arguments=%i, locals=%i, statics=%i, in_scope_only=%i)", + arguments, locals, statics, in_scope_only); + Process *process = exe_ctx.GetProcessPtr(); if (target && process) { @@ -1156,13 +1166,13 @@ SBFrame::GetVariables (bool arguments, { if (log) log->Printf ("SBFrame::GetVariables () => error: process is running"); - } + } } if (log) - { - log->Printf ("SBFrame(%p)::GetVariables (...) => SBValueList(%p)", frame, value_list.opaque_ptr()); - } + log->Printf ("SBFrame(%p)::GetVariables (...) => SBValueList(%p)", + static_cast(frame), + static_cast(value_list.opaque_ptr())); return value_list; } @@ -1207,11 +1217,13 @@ SBFrame::GetRegisters () { if (log) log->Printf ("SBFrame::GetRegisters () => error: process is running"); - } + } } if (log) - log->Printf ("SBFrame(%p)::GetRegisters () => SBValueList(%p)", frame, value_list.opaque_ptr()); + log->Printf ("SBFrame(%p)::GetRegisters () => SBValueList(%p)", + static_cast(frame), + static_cast(value_list.opaque_ptr())); return value_list; } @@ -1265,11 +1277,13 @@ SBFrame::FindRegister (const char *name) { if (log) log->Printf ("SBFrame::FindRegister () => error: process is running"); - } + } } if (log) - log->Printf ("SBFrame(%p)::FindRegister () => SBValue(%p)", frame, value_sp.get()); + log->Printf ("SBFrame(%p)::FindRegister () => SBValue(%p)", + static_cast(frame), + static_cast(value_sp.get())); return result; } @@ -1355,19 +1369,19 @@ lldb::SBValue SBFrame::EvaluateExpression (const char *expr, const SBExpressionOptions &options) { Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + Log *expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - ExecutionResults exe_results = eExecutionSetupError; + ExpressionResults exe_results = eExpressionSetupError; SBValue expr_result; - + if (expr == NULL || expr[0] == '\0') { if (log) log->Printf ("SBFrame::EvaluateExpression called with an empty expression"); return expr_result; } - + ValueObjectSP expr_value_sp; Mutex::Locker api_locker; @@ -1379,7 +1393,7 @@ SBFrame::EvaluateExpression (const char *expr, const SBExpressionOptions &option StackFrame *frame = NULL; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); - + if (target && process) { Process::StopLocker stop_locker; @@ -1395,7 +1409,7 @@ SBFrame::EvaluateExpression (const char *expr, const SBExpressionOptions &option Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s", expr, options.GetFetchDynamicValue(), frame_description.GetString().c_str()); } - + exe_results = target->EvaluateExpression (expr, frame, expr_value_sp, @@ -1415,21 +1429,18 @@ SBFrame::EvaluateExpression (const char *expr, const SBExpressionOptions &option { if (log) log->Printf ("SBFrame::EvaluateExpression () => error: process is running"); - } + } } #ifndef LLDB_DISABLE_PYTHON if (expr_log) - expr_log->Printf("** [SBFrame::EvaluateExpression] Expression result is %s, summary %s **", - expr_result.GetValue(), - expr_result.GetSummary()); - + expr_log->Printf("** [SBFrame::EvaluateExpression] Expression result is %s, summary %s **", + expr_result.GetValue(), expr_result.GetSummary()); + if (log) - log->Printf ("SBFrame(%p)::EvaluateExpression (expr=\"%s\") => SBValue(%p) (execution result=%d)", - frame, - expr, - expr_value_sp.get(), - exe_results); + log->Printf ("SBFrame(%p)::EvaluateExpression (expr=\"%s\") => SBValue(%p) (execution result=%d)", + static_cast(frame), expr, + static_cast(expr_value_sp.get()), exe_results); #endif return expr_result; diff --git a/source/API/SBFunction.cpp b/source/API/SBFunction.cpp index bb7ea2e9f202..3d185da17f26 100644 --- a/source/API/SBFunction.cpp +++ b/source/API/SBFunction.cpp @@ -66,9 +66,11 @@ SBFunction::GetName() const if (log) { if (cstr) - log->Printf ("SBFunction(%p)::GetName () => \"%s\"", m_opaque_ptr, cstr); + log->Printf ("SBFunction(%p)::GetName () => \"%s\"", + static_cast(m_opaque_ptr), cstr); else - log->Printf ("SBFunction(%p)::GetName () => NULL", m_opaque_ptr); + log->Printf ("SBFunction(%p)::GetName () => NULL", + static_cast(m_opaque_ptr)); } return cstr; } @@ -83,9 +85,11 @@ SBFunction::GetMangledName () const if (log) { if (cstr) - log->Printf ("SBFunction(%p)::GetMangledName () => \"%s\"", m_opaque_ptr, cstr); + log->Printf ("SBFunction(%p)::GetMangledName () => \"%s\"", + static_cast(m_opaque_ptr), cstr); else - log->Printf ("SBFunction(%p)::GetMangledName () => NULL", m_opaque_ptr); + log->Printf ("SBFunction(%p)::GetMangledName () => NULL", + static_cast(m_opaque_ptr)); } return cstr; } diff --git a/source/API/SBHostOS.cpp b/source/API/SBHostOS.cpp index 166403103ad5..ec1e2f2e9cba 100644 --- a/source/API/SBHostOS.cpp +++ b/source/API/SBHostOS.cpp @@ -12,6 +12,7 @@ #include "lldb/Host/FileSpec.h" #include "lldb/Core/Log.h" #include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" using namespace lldb; using namespace lldb_private; @@ -22,7 +23,7 @@ SBFileSpec SBHostOS::GetProgramFileSpec () { SBFileSpec sb_filespec; - sb_filespec.SetFileSpec (Host::GetProgramFileSpec ()); + sb_filespec.SetFileSpec(HostInfo::GetProgramFileSpec()); return sb_filespec; } @@ -31,18 +32,29 @@ SBHostOS::GetLLDBPythonPath () { SBFileSpec sb_lldb_python_filespec; FileSpec lldb_python_spec; - if (Host::GetLLDBPath (ePathTypePythonDir, lldb_python_spec)) + if (HostInfo::GetLLDBPath(ePathTypePythonDir, lldb_python_spec)) { sb_lldb_python_filespec.SetFileSpec (lldb_python_spec); } return sb_lldb_python_filespec; } + +SBFileSpec +SBHostOS::GetLLDBPath (lldb::PathType path_type) +{ + SBFileSpec sb_fspec; + FileSpec fspec; + if (HostInfo::GetLLDBPath(path_type, fspec)) + sb_fspec.SetFileSpec (fspec); + return sb_fspec; +} + lldb::thread_t SBHostOS::ThreadCreate ( const char *name, - thread_func_t thread_function, + lldb::thread_func_t thread_function, void *thread_arg, SBError *error_ptr ) @@ -50,8 +62,10 @@ SBHostOS::ThreadCreate Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBHostOS::ThreadCreate (name=\"%s\", thread_function=%p, thread_arg=%p, error_ptr=%p)", name, - thread_function, thread_arg, error_ptr); + log->Printf ("SBHostOS::ThreadCreate (name=\"%s\", thread_function=%p, thread_arg=%p, error_ptr=%p)", + name, reinterpret_cast(reinterpret_cast(thread_function)), + static_cast(thread_arg), + static_cast(error_ptr)); // FIXME: You should log the return value? @@ -77,7 +91,7 @@ SBHostOS::ThreadDetach (lldb::thread_t thread, SBError *error_ptr) } bool -SBHostOS::ThreadJoin (lldb::thread_t thread, thread_result_t *result, SBError *error_ptr) +SBHostOS::ThreadJoin (lldb::thread_t thread, lldb::thread_result_t *result, SBError *error_ptr) { return Host::ThreadJoin (thread, result, error_ptr ? error_ptr->get() : NULL); } diff --git a/source/API/SBLineEntry.cpp b/source/API/SBLineEntry.cpp index 0864a2e006c3..833eea3e35c4 100644 --- a/source/API/SBLineEntry.cpp +++ b/source/API/SBLineEntry.cpp @@ -66,7 +66,6 @@ SBLineEntry::~SBLineEntry () SBAddress SBLineEntry::GetStartAddress () const { - SBAddress sb_address; if (m_opaque_ap.get()) sb_address.SetAddress(&m_opaque_ap->range.GetBaseAddress()); @@ -78,8 +77,9 @@ SBLineEntry::GetStartAddress () const const Address *addr = sb_address.get(); if (addr) addr->Dump (&sstr, NULL, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleInvalid, 4); - log->Printf ("SBLineEntry(%p)::GetStartAddress () => SBAddress (%p): %s", - m_opaque_ap.get(), sb_address.get(), sstr.GetData()); + log->Printf ("SBLineEntry(%p)::GetStartAddress () => SBAddress (%p): %s", + static_cast(m_opaque_ap.get()), + static_cast(sb_address.get()), sstr.GetData()); } return sb_address; @@ -101,8 +101,9 @@ SBLineEntry::GetEndAddress () const const Address *addr = sb_address.get(); if (addr) addr->Dump (&sstr, NULL, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleInvalid, 4); - log->Printf ("SBLineEntry(%p)::GetEndAddress () => SBAddress (%p): %s", - m_opaque_ap.get(), sb_address.get(), sstr.GetData()); + log->Printf ("SBLineEntry(%p)::GetEndAddress () => SBAddress (%p): %s", + static_cast(m_opaque_ap.get()), + static_cast(sb_address.get()), sstr.GetData()); } return sb_address; } @@ -127,8 +128,10 @@ SBLineEntry::GetFileSpec () const { SBStream sstr; sb_file_spec.GetDescription (sstr); - log->Printf ("SBLineEntry(%p)::GetFileSpec () => SBFileSpec(%p): %s", m_opaque_ap.get(), - sb_file_spec.get(), sstr.GetData()); + log->Printf ("SBLineEntry(%p)::GetFileSpec () => SBFileSpec(%p): %s", + static_cast(m_opaque_ap.get()), + static_cast(sb_file_spec.get()), + sstr.GetData()); } return sb_file_spec; @@ -144,7 +147,8 @@ SBLineEntry::GetLine () const line = m_opaque_ap->line; if (log) - log->Printf ("SBLineEntry(%p)::GetLine () => %u", m_opaque_ap.get(), line); + log->Printf ("SBLineEntry(%p)::GetLine () => %u", + static_cast(m_opaque_ap.get()), line); return line; } diff --git a/source/API/SBListener.cpp b/source/API/SBListener.cpp index 2e67b4c24e86..bad9ba82bc91 100644 --- a/source/API/SBListener.cpp +++ b/source/API/SBListener.cpp @@ -42,7 +42,7 @@ SBListener::SBListener (const char *name) : if (log) log->Printf ("SBListener::SBListener (name=\"%s\") => SBListener(%p)", - name, m_opaque_ptr); + name, static_cast(m_opaque_ptr)); } @@ -110,7 +110,7 @@ SBListener::StartListeningForEventClass (SBDebugger &debugger, else return 0; } - + bool SBListener::StopListeningForEventClass (SBDebugger &debugger, const char *broadcaster_class, @@ -127,7 +127,7 @@ SBListener::StopListeningForEventClass (SBDebugger &debugger, else return false; } - + uint32_t SBListener::StartListeningForEvents (const SBBroadcaster& broadcaster, uint32_t event_mask) { @@ -136,23 +136,23 @@ SBListener::StartListeningForEvents (const SBBroadcaster& broadcaster, uint32_t { acquired_event_mask = m_opaque_ptr->StartListeningForEvents (broadcaster.get(), event_mask); } - + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); if (log) { StreamString sstr_requested; StreamString sstr_acquired; - + Broadcaster *lldb_broadcaster = broadcaster.get(); if (lldb_broadcaster) { const bool got_requested_names = lldb_broadcaster->GetEventNames (sstr_requested, event_mask, false); const bool got_acquired_names = lldb_broadcaster->GetEventNames (sstr_acquired, acquired_event_mask, false); log->Printf ("SBListener(%p)::StartListeneingForEvents (SBBroadcaster(%p): %s, event_mask=0x%8.8x%s%s%s) => 0x%8.8x%s%s%s", - m_opaque_ptr, - lldb_broadcaster, - lldb_broadcaster->GetBroadcasterName().GetCString(), - event_mask, + static_cast(m_opaque_ptr), + static_cast(lldb_broadcaster), + lldb_broadcaster->GetBroadcasterName().GetCString(), + event_mask, got_requested_names ? " (" : "", sstr_requested.GetData(), got_requested_names ? ")" : "", @@ -163,12 +163,10 @@ SBListener::StartListeningForEvents (const SBBroadcaster& broadcaster, uint32_t } else { - log->Printf ("SBListener(%p)::StartListeneingForEvents (SBBroadcaster(%p), event_mask=0x%8.8x) => 0x%8.8x", - m_opaque_ptr, - lldb_broadcaster, - event_mask, + log->Printf ("SBListener(%p)::StartListeneingForEvents (SBBroadcaster(%p), event_mask=0x%8.8x) => 0x%8.8x", + static_cast(m_opaque_ptr), + static_cast(lldb_broadcaster), event_mask, acquired_event_mask); - } } @@ -194,12 +192,14 @@ SBListener::WaitForEvent (uint32_t timeout_secs, SBEvent &event) if (timeout_secs == UINT32_MAX) { log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=INFINITE, SBEvent(%p))...", - m_opaque_ptr, event.get()); + static_cast(m_opaque_ptr), + static_cast(event.get())); } else { log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=%d, SBEvent(%p))...", - m_opaque_ptr, timeout_secs, event.get()); + static_cast(m_opaque_ptr), timeout_secs, + static_cast(event.get())); } } bool success = false; @@ -226,12 +226,14 @@ SBListener::WaitForEvent (uint32_t timeout_secs, SBEvent &event) if (timeout_secs == UINT32_MAX) { log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=INFINITE, SBEvent(%p)) => %i", - m_opaque_ptr, event.get(), success); + static_cast(m_opaque_ptr), + static_cast(event.get()), success); } else { log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=%d, SBEvent(%p)) => %i", - m_opaque_ptr, timeout_secs, event.get(), success); + static_cast(m_opaque_ptr), timeout_secs, + static_cast(event.get()), success); } } if (!success) diff --git a/source/API/SBModule.cpp b/source/API/SBModule.cpp index c8543d4de298..0d7dda1aa1f7 100644 --- a/source/API/SBModule.cpp +++ b/source/API/SBModule.cpp @@ -110,10 +110,9 @@ SBModule::GetFileSpec () const file_spec.SetFileSpec(module_sp->GetFileSpec()); if (log) - { - log->Printf ("SBModule(%p)::GetFileSpec () => SBFileSpec(%p)", - module_sp.get(), file_spec.get()); - } + log->Printf ("SBModule(%p)::GetFileSpec () => SBFileSpec(%p)", + static_cast(module_sp.get()), + static_cast(file_spec.get())); return file_spec; } @@ -122,20 +121,18 @@ lldb::SBFileSpec SBModule::GetPlatformFileSpec () const { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + SBFileSpec file_spec; ModuleSP module_sp (GetSP ()); if (module_sp) file_spec.SetFileSpec(module_sp->GetPlatformFileSpec()); - + if (log) - { - log->Printf ("SBModule(%p)::GetPlatformFileSpec () => SBFileSpec(%p)", - module_sp.get(), file_spec.get()); - } - + log->Printf ("SBModule(%p)::GetPlatformFileSpec () => SBFileSpec(%p)", + static_cast(module_sp.get()), + static_cast(file_spec.get())); + return file_spec; - } bool @@ -143,22 +140,19 @@ SBModule::SetPlatformFileSpec (const lldb::SBFileSpec &platform_file) { bool result = false; Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + ModuleSP module_sp (GetSP ()); if (module_sp) { module_sp->SetPlatformFileSpec(*platform_file); result = true; } - + if (log) - { - log->Printf ("SBModule(%p)::SetPlatformFileSpec (SBFileSpec(%p (%s)) => %i", - module_sp.get(), - platform_file.get(), - platform_file->GetPath().c_str(), - result); - } + log->Printf ("SBModule(%p)::SetPlatformFileSpec (SBFileSpec(%p (%s)) => %i", + static_cast(module_sp.get()), + static_cast(platform_file.get()), + platform_file->GetPath().c_str(), result); return result; } @@ -201,10 +195,12 @@ SBModule::GetUUIDBytes () const { StreamString s; module_sp->GetUUID().Dump (&s); - log->Printf ("SBModule(%p)::GetUUIDBytes () => %s", module_sp.get(), s.GetData()); + log->Printf ("SBModule(%p)::GetUUIDBytes () => %s", + static_cast(module_sp.get()), s.GetData()); } else - log->Printf ("SBModule(%p)::GetUUIDBytes () => NULL", module_sp.get()); + log->Printf ("SBModule(%p)::GetUUIDBytes () => NULL", + static_cast(module_sp.get())); } return uuid_bytes; } @@ -225,6 +221,7 @@ SBModule::GetUUIDString () const if (!uuid_string.empty()) { strncpy (uuid_string_buffer, uuid_string.c_str(), sizeof (uuid_string_buffer)); + uuid_string_buffer[sizeof (uuid_string_buffer) - 1] = '\0'; uuid_c_string = uuid_string_buffer; } @@ -234,10 +231,12 @@ SBModule::GetUUIDString () const { StreamString s; module_sp->GetUUID().Dump (&s); - log->Printf ("SBModule(%p)::GetUUIDString () => %s", module_sp.get(), s.GetData()); + log->Printf ("SBModule(%p)::GetUUIDString () => %s", + static_cast(module_sp.get()), s.GetData()); } else - log->Printf ("SBModule(%p)::GetUUIDString () => NULL", module_sp.get()); + log->Printf ("SBModule(%p)::GetUUIDString () => NULL", + static_cast(module_sp.get())); } return uuid_c_string; } diff --git a/source/API/SBProcess.cpp b/source/API/SBProcess.cpp index 235388b5f25c..41efd86177d6 100644 --- a/source/API/SBProcess.cpp +++ b/source/API/SBProcess.cpp @@ -40,6 +40,7 @@ #include "lldb/API/SBThread.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBStringList.h" +#include "lldb/API/SBUnixSignals.h" using namespace lldb; using namespace lldb_private; @@ -148,20 +149,17 @@ SBProcess::RemoteLaunch (char const **argv, lldb::SBError& error) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - if (log) { + if (log) log->Printf ("SBProcess(%p)::RemoteLaunch (argv=%p, envp=%p, stdin=%s, stdout=%s, stderr=%s, working-dir=%s, launch_flags=0x%x, stop_at_entry=%i, &error (%p))...", - m_opaque_wp.lock().get(), - argv, - envp, - stdin_path ? stdin_path : "NULL", - stdout_path ? stdout_path : "NULL", - stderr_path ? stderr_path : "NULL", + static_cast(m_opaque_wp.lock().get()), + static_cast(argv), static_cast(envp), + stdin_path ? stdin_path : "NULL", + stdout_path ? stdout_path : "NULL", + stderr_path ? stderr_path : "NULL", working_directory ? working_directory : "NULL", - launch_flags, - stop_at_entry, - error.get()); - } - + launch_flags, stop_at_entry, + static_cast(error.get())); + ProcessSP process_sp(GetSP()); if (process_sp) { @@ -170,7 +168,7 @@ SBProcess::RemoteLaunch (char const **argv, { if (stop_at_entry) launch_flags |= eLaunchFlagStopAtEntry; - ProcessLaunchInfo launch_info (stdin_path, + ProcessLaunchInfo launch_info (stdin_path, stdout_path, stderr_path, working_directory, @@ -193,13 +191,15 @@ SBProcess::RemoteLaunch (char const **argv, { error.SetErrorString ("unable to attach pid"); } - + if (log) { SBStream sstr; error.GetDescription (sstr); - log->Printf ("SBProcess(%p)::RemoteLaunch (...) => SBError (%p): %s", process_sp.get(), error.get(), sstr.GetData()); + log->Printf ("SBProcess(%p)::RemoteLaunch (...) => SBError (%p): %s", + static_cast(process_sp.get()), + static_cast(error.get()), sstr.GetData()); } - + return error.Success(); } @@ -214,7 +214,7 @@ SBProcess::RemoteAttachToProcessWithID (lldb::pid_t pid, lldb::SBError& error) { ProcessAttachInfo attach_info; attach_info.SetProcessID (pid); - error.SetError (process_sp->Attach (attach_info)); + error.SetError (process_sp->Attach (attach_info)); } else { @@ -230,7 +230,9 @@ SBProcess::RemoteAttachToProcessWithID (lldb::pid_t pid, lldb::SBError& error) if (log) { SBStream sstr; error.GetDescription (sstr); - log->Printf ("SBProcess(%p)::RemoteAttachToProcessWithID (%" PRIu64 ") => SBError (%p): %s", process_sp.get(), pid, error.get(), sstr.GetData()); + log->Printf ("SBProcess(%p)::RemoteAttachToProcessWithID (%" PRIu64 ") => SBError (%p): %s", + static_cast(process_sp.get()), pid, + static_cast(error.get()), sstr.GetData()); } return error.Success(); @@ -247,14 +249,15 @@ SBProcess::GetNumThreads () if (process_sp) { Process::StopLocker stop_locker; - + const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock()); Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); num_threads = process_sp->GetThreadList().GetSize(can_update); } if (log) - log->Printf ("SBProcess(%p)::GetNumThreads () => %d", process_sp.get(), num_threads); + log->Printf ("SBProcess(%p)::GetNumThreads () => %d", + static_cast(process_sp.get()), num_threads); return num_threads; } @@ -275,9 +278,9 @@ SBProcess::GetSelectedThread () const } if (log) - { - log->Printf ("SBProcess(%p)::GetSelectedThread () => SBThread(%p)", process_sp.get(), thread_sp.get()); - } + log->Printf ("SBProcess(%p)::GetSelectedThread () => SBThread(%p)", + static_cast(process_sp.get()), + static_cast(thread_sp.get())); return sb_thread; } @@ -286,7 +289,7 @@ SBThread SBProcess::CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + SBThread sb_thread; ThreadSP thread_sp; ProcessSP process_sp(GetSP()); @@ -296,10 +299,12 @@ SBProcess::CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context) thread_sp = process_sp->CreateOSPluginThread(tid, context); sb_thread.SetThread (thread_sp); } - + if (log) - log->Printf ("SBProcess(%p)::CreateOSPluginThread (tid=0x%" PRIx64 ", context=0x%" PRIx64 ") => SBThread(%p)", process_sp.get(), tid, context, thread_sp.get()); - + log->Printf ("SBProcess(%p)::CreateOSPluginThread (tid=0x%" PRIx64 ", context=0x%" PRIx64 ") => SBThread(%p)", + static_cast(process_sp.get()), tid, context, + static_cast(thread_sp.get())); + return sb_thread; } @@ -316,9 +321,11 @@ SBProcess::GetTarget() const target_sp = process_sp->GetTarget().shared_from_this(); sb_target.SetSP (target_sp); } - + if (log) - log->Printf ("SBProcess(%p)::GetTarget () => SBTarget(%p)", process_sp.get(), target_sp.get()); + log->Printf ("SBProcess(%p)::GetTarget () => SBTarget(%p)", + static_cast(process_sp.get()), + static_cast(target_sp.get())); return sb_target; } @@ -336,13 +343,12 @@ SBProcess::PutSTDIN (const char *src, size_t src_len) Error error; ret_val = process_sp->PutSTDIN (src, src_len, error); } - + if (log) - log->Printf ("SBProcess(%p)::PutSTDIN (src=\"%s\", src_len=%d) => %zu", - process_sp.get(), - src, - (uint32_t) src_len, - ret_val); + log->Printf("SBProcess(%p)::PutSTDIN (src=\"%s\", src_len=%" PRIu64 ") => %" PRIu64, + static_cast(process_sp.get()), src, + static_cast(src_len), + static_cast(ret_val)); return ret_val; } @@ -357,15 +363,14 @@ SBProcess::GetSTDOUT (char *dst, size_t dst_len) const Error error; bytes_read = process_sp->GetSTDOUT (dst, dst_len, error); } - + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBProcess(%p)::GetSTDOUT (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64, - process_sp.get(), - (int) bytes_read, - dst, - (uint64_t)dst_len, - (uint64_t)bytes_read); + static_cast(process_sp.get()), + static_cast(bytes_read), dst, + static_cast(dst_len), + static_cast(bytes_read)); return bytes_read; } @@ -384,11 +389,10 @@ SBProcess::GetSTDERR (char *dst, size_t dst_len) const Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBProcess(%p)::GetSTDERR (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64, - process_sp.get(), - (int) bytes_read, - dst, - (uint64_t)dst_len, - (uint64_t)bytes_read); + static_cast(process_sp.get()), + static_cast(bytes_read), dst, + static_cast(dst_len), + static_cast(bytes_read)); return bytes_read; } @@ -403,16 +407,15 @@ SBProcess::GetAsyncProfileData(char *dst, size_t dst_len) const Error error; bytes_read = process_sp->GetAsyncProfileData (dst, dst_len, error); } - + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBProcess(%p)::GetProfileData (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64, - process_sp.get(), - (int) bytes_read, - dst, - (uint64_t)dst_len, - (uint64_t)bytes_read); - + static_cast(process_sp.get()), + static_cast(bytes_read), dst, + static_cast(dst_len), + static_cast(bytes_read)); + return bytes_read; } @@ -483,7 +486,8 @@ SBProcess::SetSelectedThreadByID (lldb::tid_t tid) if (log) log->Printf ("SBProcess(%p)::SetSelectedThreadByID (tid=0x%4.4" PRIx64 ") => %s", - process_sp.get(), tid, (ret_val ? "true" : "false")); + static_cast(process_sp.get()), tid, + (ret_val ? "true" : "false")); return ret_val; } @@ -502,8 +506,9 @@ SBProcess::SetSelectedThreadByIndexID (uint32_t index_id) } if (log) - log->Printf ("SBProcess(%p)::SetSelectedThreadByID (tid=0x%x) => %s", - process_sp.get(), index_id, (ret_val ? "true" : "false")); + log->Printf ("SBProcess(%p)::SetSelectedThreadByID (tid=0x%x) => %s", + static_cast(process_sp.get()), index_id, + (ret_val ? "true" : "false")); return ret_val; } @@ -526,10 +531,10 @@ SBProcess::GetThreadAtIndex (size_t index) } if (log) - { log->Printf ("SBProcess(%p)::GetThreadAtIndex (index=%d) => SBThread(%p)", - process_sp.get(), (uint32_t) index, thread_sp.get()); - } + static_cast(process_sp.get()), + static_cast(index), + static_cast(thread_sp.get())); return sb_thread; } @@ -544,13 +549,14 @@ SBProcess::GetNumQueues () if (process_sp) { Process::StopLocker stop_locker; - + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); num_queues = process_sp->GetQueueList().GetSize(); } if (log) - log->Printf ("SBProcess(%p)::GetNumQueues () => %d", process_sp.get(), num_queues); + log->Printf ("SBProcess(%p)::GetNumQueues () => %d", + static_cast(process_sp.get()), num_queues); return num_queues; } @@ -572,10 +578,10 @@ SBProcess::GetQueueAtIndex (size_t index) } if (log) - { log->Printf ("SBProcess(%p)::GetQueueAtIndex (index=%d) => SBQueue(%p)", - process_sp.get(), (uint32_t) index, queue_sp.get()); - } + static_cast(process_sp.get()), + static_cast(index), + static_cast(queue_sp.get())); return sb_queue; } @@ -610,8 +616,8 @@ SBProcess::GetState () Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBProcess(%p)::GetState () => %s", - process_sp.get(), + log->Printf ("SBProcess(%p)::GetState () => %s", + static_cast(process_sp.get()), lldb_private::StateAsCString (ret_val)); return ret_val; @@ -630,8 +636,9 @@ SBProcess::GetExitStatus () } Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBProcess(%p)::GetExitStatus () => %i (0x%8.8x)", - process_sp.get(), exit_status, exit_status); + log->Printf ("SBProcess(%p)::GetExitStatus () => %i (0x%8.8x)", + static_cast(process_sp.get()), exit_status, + exit_status); return exit_status; } @@ -648,8 +655,8 @@ SBProcess::GetExitDescription () } Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBProcess(%p)::GetExitDescription () => %s", - process_sp.get(), exit_desc); + log->Printf ("SBProcess(%p)::GetExitDescription () => %s", + static_cast(process_sp.get()), exit_desc); return exit_desc; } @@ -663,7 +670,8 @@ SBProcess::GetProcessID () Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBProcess(%p)::GetProcessID () => %" PRIu64, process_sp.get(), ret_val); + log->Printf ("SBProcess(%p)::GetProcessID () => %" PRIu64, + static_cast(process_sp.get()), ret_val); return ret_val; } @@ -677,7 +685,8 @@ SBProcess::GetUniqueID() ret_val = process_sp->GetUniqueID(); Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBProcess(%p)::GetUniqueID () => %" PRIu32, process_sp.get(), ret_val); + log->Printf ("SBProcess(%p)::GetUniqueID () => %" PRIu32, + static_cast(process_sp.get()), ret_val); return ret_val; } @@ -688,10 +697,11 @@ SBProcess::GetByteOrder () const ProcessSP process_sp(GetSP()); if (process_sp) byteOrder = process_sp->GetTarget().GetArchitecture().GetByteOrder(); - + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBProcess(%p)::GetByteOrder () => %d", process_sp.get(), byteOrder); + log->Printf ("SBProcess(%p)::GetByteOrder () => %d", + static_cast(process_sp.get()), byteOrder); return byteOrder; } @@ -706,7 +716,8 @@ SBProcess::GetAddressByteSize () const Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBProcess(%p)::GetAddressByteSize () => %d", process_sp.get(), size); + log->Printf ("SBProcess(%p)::GetAddressByteSize () => %d", + static_cast(process_sp.get()), size); return size; } @@ -715,24 +726,26 @@ SBError SBProcess::Continue () { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + SBError sb_error; ProcessSP process_sp(GetSP()); if (log) - log->Printf ("SBProcess(%p)::Continue ()...", process_sp.get()); + log->Printf ("SBProcess(%p)::Continue ()...", + static_cast(process_sp.get())); if (process_sp) { Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); - + Error error (process_sp->Resume()); if (error.Success()) { if (process_sp->GetTarget().GetDebugger().GetAsyncExecution () == false) { if (log) - log->Printf ("SBProcess(%p)::Continue () waiting for process to stop...", process_sp.get()); + log->Printf ("SBProcess(%p)::Continue () waiting for process to stop...", + static_cast(process_sp.get())); process_sp->WaitForProcessToStop (NULL); } } @@ -745,7 +758,9 @@ SBProcess::Continue () { SBStream sstr; sb_error.GetDescription (sstr); - log->Printf ("SBProcess(%p)::Continue () => SBError (%p): %s", process_sp.get(), sb_error.get(), sstr.GetData()); + log->Printf ("SBProcess(%p)::Continue () => SBError (%p): %s", + static_cast(process_sp.get()), + static_cast(sb_error.get()), sstr.GetData()); } return sb_error; @@ -770,10 +785,9 @@ SBProcess::Destroy () { SBStream sstr; sb_error.GetDescription (sstr); - log->Printf ("SBProcess(%p)::Destroy () => SBError (%p): %s", - process_sp.get(), - sb_error.get(), - sstr.GetData()); + log->Printf ("SBProcess(%p)::Destroy () => SBError (%p): %s", + static_cast(process_sp.get()), + static_cast(sb_error.get()), sstr.GetData()); } return sb_error; @@ -792,16 +806,15 @@ SBProcess::Stop () } else sb_error.SetErrorString ("SBProcess is invalid"); - + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { SBStream sstr; sb_error.GetDescription (sstr); - log->Printf ("SBProcess(%p)::Stop () => SBError (%p): %s", - process_sp.get(), - sb_error.get(), - sstr.GetData()); + log->Printf ("SBProcess(%p)::Stop () => SBError (%p): %s", + static_cast(process_sp.get()), + static_cast(sb_error.get()), sstr.GetData()); } return sb_error; @@ -825,10 +838,9 @@ SBProcess::Kill () { SBStream sstr; sb_error.GetDescription (sstr); - log->Printf ("SBProcess(%p)::Kill () => SBError (%p): %s", - process_sp.get(), - sb_error.get(), - sstr.GetData()); + log->Printf ("SBProcess(%p)::Kill () => SBError (%p): %s", + static_cast(process_sp.get()), + static_cast(sb_error.get()), sstr.GetData()); } return sb_error; @@ -869,21 +881,32 @@ SBProcess::Signal (int signo) sb_error.SetError (process_sp->Signal (signo)); } else - sb_error.SetErrorString ("SBProcess is invalid"); + sb_error.SetErrorString ("SBProcess is invalid"); Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { SBStream sstr; sb_error.GetDescription (sstr); - log->Printf ("SBProcess(%p)::Signal (signo=%i) => SBError (%p): %s", - process_sp.get(), - signo, - sb_error.get(), - sstr.GetData()); + log->Printf ("SBProcess(%p)::Signal (signo=%i) => SBError (%p): %s", + static_cast(process_sp.get()), signo, + static_cast(sb_error.get()), sstr.GetData()); } return sb_error; } +SBUnixSignals +SBProcess::GetUnixSignals() +{ + SBUnixSignals sb_unix_signals; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + sb_unix_signals.SetSP(process_sp); + } + + return sb_unix_signals; +} + void SBProcess::SendAsyncInterrupt () { @@ -911,12 +934,9 @@ SBProcess::GetThreadByID (tid_t tid) Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - { log->Printf ("SBProcess(%p)::GetThreadByID (tid=0x%4.4" PRIx64 ") => SBThread (%p)", - process_sp.get(), - tid, - thread_sp.get()); - } + static_cast(process_sp.get()), tid, + static_cast(thread_sp.get())); return sb_thread; } @@ -938,12 +958,9 @@ SBProcess::GetThreadByIndexID (uint32_t index_id) Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - { - log->Printf ("SBProcess(%p)::GetThreadByID (tid=0x%x) => SBThread (%p)", - process_sp.get(), - index_id, - thread_sp.get()); - } + log->Printf ("SBProcess(%p)::GetThreadByID (tid=0x%x) => SBThread (%p)", + static_cast(process_sp.get()), index_id, + static_cast(thread_sp.get())); return sb_thread; } @@ -954,9 +971,10 @@ SBProcess::GetStateFromEvent (const SBEvent &event) Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); StateType ret_val = Process::ProcessEventData::GetStateFromEvent (event.get()); - + if (log) - log->Printf ("SBProcess::GetStateFromEvent (event.sp=%p) => %s", event.get(), + log->Printf ("SBProcess::GetStateFromEvent (event.sp=%p) => %s", + static_cast(event.get()), lldb_private::StateAsCString (ret_val)); return ret_val; @@ -1003,8 +1021,9 @@ SBProcess::GetBroadcaster () const SBBroadcaster broadcaster(process_sp.get(), false); if (log) - log->Printf ("SBProcess(%p)::GetBroadcaster () => SBBroadcaster (%p)", process_sp.get(), - broadcaster.get()); + log->Printf ("SBProcess(%p)::GetBroadcaster () => SBBroadcaster (%p)", + static_cast(process_sp.get()), + static_cast(broadcaster.get())); return broadcaster; } @@ -1025,15 +1044,11 @@ SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error ProcessSP process_sp(GetSP()); if (log) - { log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%" PRIx64 ", dst=%p, dst_len=%" PRIu64 ", SBError (%p))...", - process_sp.get(), - addr, - dst, - (uint64_t)dst_len, - sb_error.get()); - } - + static_cast(process_sp.get()), addr, + static_cast(dst), static_cast(dst_len), + static_cast(sb_error.get())); + if (process_sp) { Process::StopLocker stop_locker; @@ -1045,7 +1060,8 @@ SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error else { if (log) - log->Printf ("SBProcess(%p)::ReadMemory() => error: process is running", process_sp.get()); + log->Printf ("SBProcess(%p)::ReadMemory() => error: process is running", + static_cast(process_sp.get())); sb_error.SetErrorString("process is running"); } } @@ -1059,13 +1075,10 @@ SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error SBStream sstr; sb_error.GetDescription (sstr); log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%" PRIx64 ", dst=%p, dst_len=%" PRIu64 ", SBError (%p): %s) => %" PRIu64, - process_sp.get(), - addr, - dst, - (uint64_t)dst_len, - sb_error.get(), - sstr.GetData(), - (uint64_t)bytes_read); + static_cast(process_sp.get()), addr, + static_cast(dst), static_cast(dst_len), + static_cast(sb_error.get()), sstr.GetData(), + static_cast(bytes_read)); } return bytes_read; @@ -1088,7 +1101,8 @@ SBProcess::ReadCStringFromMemory (addr_t addr, void *buf, size_t size, lldb::SBE { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBProcess(%p)::ReadCStringFromMemory() => error: process is running", process_sp.get()); + log->Printf ("SBProcess(%p)::ReadCStringFromMemory() => error: process is running", + static_cast(process_sp.get())); sb_error.SetErrorString("process is running"); } } @@ -1116,7 +1130,8 @@ SBProcess::ReadUnsignedFromMemory (addr_t addr, uint32_t byte_size, lldb::SBErro { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBProcess(%p)::ReadUnsignedFromMemory() => error: process is running", process_sp.get()); + log->Printf ("SBProcess(%p)::ReadUnsignedFromMemory() => error: process is running", + static_cast(process_sp.get())); sb_error.SetErrorString("process is running"); } } @@ -1144,7 +1159,8 @@ SBProcess::ReadPointerFromMemory (addr_t addr, lldb::SBError &sb_error) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBProcess(%p)::ReadPointerFromMemory() => error: process is running", process_sp.get()); + log->Printf ("SBProcess(%p)::ReadPointerFromMemory() => error: process is running", + static_cast(process_sp.get())); sb_error.SetErrorString("process is running"); } } @@ -1165,14 +1181,11 @@ SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &s ProcessSP process_sp(GetSP()); if (log) - { log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%" PRIx64 ", src=%p, src_len=%" PRIu64 ", SBError (%p))...", - process_sp.get(), - addr, - src, - (uint64_t)src_len, - sb_error.get()); - } + static_cast(process_sp.get()), addr, + static_cast(src), + static_cast(src_len), + static_cast(sb_error.get())); if (process_sp) { @@ -1185,7 +1198,8 @@ SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &s else { if (log) - log->Printf ("SBProcess(%p)::WriteMemory() => error: process is running", process_sp.get()); + log->Printf ("SBProcess(%p)::WriteMemory() => error: process is running", + static_cast(process_sp.get())); sb_error.SetErrorString("process is running"); } } @@ -1195,13 +1209,11 @@ SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &s SBStream sstr; sb_error.GetDescription (sstr); log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%" PRIx64 ", src=%p, src_len=%" PRIu64 ", SBError (%p): %s) => %" PRIu64, - process_sp.get(), - addr, - src, - (uint64_t)src_len, - sb_error.get(), - sstr.GetData(), - (uint64_t)bytes_written); + static_cast(process_sp.get()), addr, + static_cast(src), + static_cast(src_len), + static_cast(sb_error.get()), sstr.GetData(), + static_cast(bytes_written)); } return bytes_written; @@ -1248,7 +1260,7 @@ SBProcess::GetNumSupportedHardwareWatchpoints (lldb::SBError &sb_error) const sb_error.SetError(process_sp->GetWatchpointSupportInfo (num)); if (log) log->Printf ("SBProcess(%p)::GetNumSupportedHardwareWatchpoints () => %u", - process_sp.get(), num); + static_cast(process_sp.get()), num); } else { @@ -1273,13 +1285,14 @@ SBProcess::LoadImage (lldb::SBFileSpec &sb_image_spec, lldb::SBError &sb_error) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBProcess(%p)::LoadImage() => error: process is running", process_sp.get()); + log->Printf ("SBProcess(%p)::LoadImage() => error: process is running", + static_cast(process_sp.get())); sb_error.SetErrorString("process is running"); } } return LLDB_INVALID_IMAGE_TOKEN; } - + lldb::SBError SBProcess::UnloadImage (uint32_t image_token) { @@ -1297,7 +1310,35 @@ SBProcess::UnloadImage (uint32_t image_token) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBProcess(%p)::UnloadImage() => error: process is running", process_sp.get()); + log->Printf ("SBProcess(%p)::UnloadImage() => error: process is running", + static_cast(process_sp.get())); + sb_error.SetErrorString("process is running"); + } + } + else + sb_error.SetErrorString("invalid process"); + return sb_error; +} + +lldb::SBError +SBProcess::SendEventData (const char *event_data) +{ + lldb::SBError sb_error; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + sb_error.SetError (process_sp->SendEventData (event_data)); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::SendEventData() => error: process is running", + static_cast(process_sp.get())); sb_error.SetErrorString("process is running"); } } @@ -1334,7 +1375,8 @@ SBProcess::GetExtendedBacktraceTypeAtIndex (uint32_t idx) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf("SBProcess(%p)::GetExtendedBacktraceTypeAtIndex() => error: requested extended backtrace name out of bounds", process_sp.get()); + log->Printf("SBProcess(%p)::GetExtendedBacktraceTypeAtIndex() => error: requested extended backtrace name out of bounds", + static_cast(process_sp.get())); } } return NULL; diff --git a/source/API/SBQueue.cpp b/source/API/SBQueue.cpp index 8d67a48d6b81..b19ed72543c2 100644 --- a/source/API/SBQueue.cpp +++ b/source/API/SBQueue.cpp @@ -9,10 +9,14 @@ #include "lldb/lldb-python.h" +#include + #include "lldb/API/SBQueue.h" #include "lldb/API/SBProcess.h" #include "lldb/API/SBThread.h" +#include "lldb/API/SBQueueItem.h" + #include "lldb/Core/Log.h" #include "lldb/Target/Process.h" #include "lldb/Target/Queue.h" @@ -96,7 +100,8 @@ namespace lldb_private } Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBQueue(%p)::GetQueueID () => 0x%" PRIx64, this, result); + log->Printf ("SBQueue(%p)::GetQueueID () => 0x%" PRIx64, + static_cast(this), result); return result; } @@ -111,10 +116,11 @@ namespace lldb_private } Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBQueueImpl(%p)::GetIndexID () => %d", this, result); + log->Printf ("SBQueueImpl(%p)::GetIndexID () => %d", + static_cast(this), result); return result; } - + const char * GetName () const { @@ -124,14 +130,16 @@ namespace lldb_private { name = queue_sp->GetName(); } - + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBQueueImpl(%p)::GetName () => %s", this, name ? name : "NULL"); - + log->Printf ("SBQueueImpl(%p)::GetName () => %s", + static_cast(this), + name ? name : "NULL"); + return name; } - + void FetchThreads () { @@ -158,7 +166,7 @@ namespace lldb_private } } } - + void FetchItems () { @@ -185,12 +193,12 @@ namespace lldb_private } } } - + uint32_t GetNumThreads () { uint32_t result = 0; - + FetchThreads(); if (m_thread_list_fetched) { @@ -198,12 +206,12 @@ namespace lldb_private } return result; } - + lldb::SBThread GetThreadAtIndex (uint32_t idx) { FetchThreads(); - + SBThread sb_thread; QueueSP queue_sp = m_queue_wp.lock(); if (queue_sp && idx < m_threads.size()) @@ -220,21 +228,24 @@ namespace lldb_private } return sb_thread; } - - + uint32_t GetNumPendingItems () { uint32_t result = 0; - FetchItems(); - - if (m_pending_items_fetched) + + QueueSP queue_sp = m_queue_wp.lock(); + if (m_pending_items_fetched == false && queue_sp) + { + result = queue_sp->GetNumPendingWorkItems(); + } + else { result = m_pending_items.size(); } return result; } - + lldb::SBQueueItem GetPendingItemAtIndex (uint32_t idx) { @@ -246,7 +257,17 @@ namespace lldb_private } return result; } - + + uint32_t + GetNumRunningItems () + { + uint32_t result = 0; + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + result = queue_sp->GetNumRunningWorkItems(); + return result; + } + lldb::SBProcess GetProcess () { @@ -259,6 +280,17 @@ namespace lldb_private return result; } + lldb::QueueKind + GetKind () + { + lldb::QueueKind kind = eQueueKindUnknown; + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + kind = queue_sp->GetKind(); + + return kind; + } + private: lldb::QueueWP m_queue_wp; std::vector m_threads; // threads currently executing this queue's items @@ -301,13 +333,21 @@ SBQueue::~SBQueue() bool SBQueue::IsValid() const { - return m_opaque_sp->IsValid(); + bool is_valid = m_opaque_sp->IsValid (); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::IsValid() == %s", m_opaque_sp->GetQueueID(), + is_valid ? "true" : "false"); + return is_valid; } void SBQueue::Clear () { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::Clear()", m_opaque_sp->GetQueueID()); m_opaque_sp->Clear(); } @@ -321,48 +361,92 @@ SBQueue::SetQueue (const QueueSP& queue_sp) lldb::queue_id_t SBQueue::GetQueueID () const { - return m_opaque_sp->GetQueueID (); + lldb::queue_id_t qid = m_opaque_sp->GetQueueID (); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::GetQueueID() == 0x%" PRIx64, m_opaque_sp->GetQueueID(), (uint64_t) qid); + return qid; } uint32_t SBQueue::GetIndexID () const { - return m_opaque_sp->GetIndexID (); + uint32_t index_id = m_opaque_sp->GetIndexID (); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::GetIndexID() == 0x%" PRIx32, m_opaque_sp->GetQueueID(), index_id); + return index_id; } const char * SBQueue::GetName () const { - return m_opaque_sp->GetName (); + const char *name = m_opaque_sp->GetName (); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::GetName() == %s", m_opaque_sp->GetQueueID(), + name ? name : ""); + return name; } uint32_t SBQueue::GetNumThreads () { - return m_opaque_sp->GetNumThreads (); + uint32_t numthreads = m_opaque_sp->GetNumThreads (); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::GetNumThreads() == %d", m_opaque_sp->GetQueueID(), numthreads); + return numthreads; } SBThread SBQueue::GetThreadAtIndex (uint32_t idx) { - return m_opaque_sp->GetThreadAtIndex (idx); + SBThread th = m_opaque_sp->GetThreadAtIndex (idx); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::GetThreadAtIndex(%d)", m_opaque_sp->GetQueueID(), idx); + return th; } uint32_t SBQueue::GetNumPendingItems () { - return m_opaque_sp->GetNumPendingItems (); + uint32_t pending_items = m_opaque_sp->GetNumPendingItems (); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::GetNumPendingItems() == %d", m_opaque_sp->GetQueueID(), pending_items); + return pending_items; } SBQueueItem SBQueue::GetPendingItemAtIndex (uint32_t idx) { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::GetPendingItemAtIndex(%d)", m_opaque_sp->GetQueueID(), idx); return m_opaque_sp->GetPendingItemAtIndex (idx); } +uint32_t +SBQueue::GetNumRunningItems () +{ + uint32_t running_items = m_opaque_sp->GetNumRunningItems (); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::GetNumRunningItems() == %d", m_opaque_sp->GetQueueID(), running_items); + return running_items; +} + SBProcess SBQueue::GetProcess () { return m_opaque_sp->GetProcess(); } + +lldb::QueueKind +SBQueue::GetKind () +{ + return m_opaque_sp->GetKind(); +} diff --git a/source/API/SBQueueItem.cpp b/source/API/SBQueueItem.cpp index 481d51e55426..6a1aa7bec61a 100644 --- a/source/API/SBQueueItem.cpp +++ b/source/API/SBQueueItem.cpp @@ -14,6 +14,8 @@ #include "lldb/API/SBQueueItem.h" #include "lldb/API/SBThread.h" #include "lldb/Core/Address.h" +#include "lldb/Core/Log.h" +#include "lldb/Target/Process.h" #include "lldb/Target/QueueItem.h" #include "lldb/Target/Thread.h" @@ -44,13 +46,23 @@ SBQueueItem::~SBQueueItem() bool SBQueueItem::IsValid() const { - return m_queue_item_sp.get() != NULL; + bool is_valid = m_queue_item_sp.get() != NULL; + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueueItem(%p)::IsValid() == %s", + static_cast(m_queue_item_sp.get()), + is_valid ? "true" : "false"); + return is_valid; } void SBQueueItem::Clear () { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueueItem(%p)::Clear()", + static_cast(m_queue_item_sp.get())); m_queue_item_sp.reset(); } @@ -66,10 +78,15 @@ lldb::QueueItemKind SBQueueItem::GetKind () const { QueueItemKind result = eQueueItemKindUnknown; + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (m_queue_item_sp) { result = m_queue_item_sp->GetKind (); } + if (log) + log->Printf("SBQueueItem(%p)::GetKind() == %d", + static_cast(m_queue_item_sp.get()), + static_cast(result)); return result; } @@ -86,10 +103,21 @@ SBAddress SBQueueItem::GetAddress () const { SBAddress result; + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (m_queue_item_sp) { result.SetAddress (&m_queue_item_sp->GetAddress()); } + if (log) + { + StreamString sstr; + const Address *addr = result.get(); + if (addr) + addr->Dump (&sstr, NULL, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleInvalid, 4); + log->Printf ("SBQueueItem(%p)::GetAddress() == SBAddress(%p): %s", + static_cast(m_queue_item_sp.get()), + static_cast(result.get()), sstr.GetData()); + } return result; } @@ -106,14 +134,34 @@ SBThread SBQueueItem::GetExtendedBacktraceThread (const char *type) { SBThread result; + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (m_queue_item_sp) { - ThreadSP thread_sp; - ConstString type_const (type); - thread_sp = m_queue_item_sp->GetExtendedBacktraceThread (type_const); - if (thread_sp) + ProcessSP process_sp = m_queue_item_sp->GetProcessSP(); + Process::StopLocker stop_locker; + if (process_sp && stop_locker.TryLock(&process_sp->GetRunLock())) { - result.SetThread (thread_sp); + ThreadSP thread_sp; + ConstString type_const (type); + thread_sp = m_queue_item_sp->GetExtendedBacktraceThread (type_const); + if (thread_sp) + { + // Save this in the Process' ExtendedThreadList so a strong pointer retains the + // object + process_sp->GetExtendedThreadList().AddThread (thread_sp); + result.SetThread (thread_sp); + if (log) + { + const char *queue_name = thread_sp->GetQueueName(); + if (queue_name == NULL) + queue_name = ""; + log->Printf ("SBQueueItem(%p)::GetExtendedBacktraceThread() = new extended Thread created (%p) with queue_id 0x%" PRIx64 " queue name '%s'", + static_cast(m_queue_item_sp.get()), + static_cast(thread_sp.get()), + static_cast(thread_sp->GetQueueID()), + queue_name); + } + } } } return result; diff --git a/source/API/SBStream.cpp b/source/API/SBStream.cpp index 531ab9f463ce..f5b5c08411c7 100644 --- a/source/API/SBStream.cpp +++ b/source/API/SBStream.cpp @@ -82,6 +82,8 @@ SBStream::RedirectToFile (const char *path, bool append) uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate; if (append) open_options |= File::eOpenOptionAppend; + else + open_options |= File::eOpenOptionTruncate; stream_file->GetFile().Open (path, open_options, lldb::eFilePermissionsFileDefault); m_opaque_ap.reset (stream_file); diff --git a/source/API/SBSymbol.cpp b/source/API/SBSymbol.cpp index ef3d0764c963..12a3b317d501 100644 --- a/source/API/SBSymbol.cpp +++ b/source/API/SBSymbol.cpp @@ -67,7 +67,8 @@ SBSymbol::GetName() const Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBSymbol(%p)::GetName () => \"%s\"", m_opaque_ptr, name ? name : ""); + log->Printf ("SBSymbol(%p)::GetName () => \"%s\"", + static_cast(m_opaque_ptr), name ? name : ""); return name; } @@ -79,7 +80,8 @@ SBSymbol::GetMangledName () const name = m_opaque_ptr->GetMangled().GetMangledName().AsCString(); Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBSymbol(%p)::GetMangledName () => \"%s\"", m_opaque_ptr, name ? name : ""); + log->Printf ("SBSymbol(%p)::GetMangledName () => \"%s\"", + static_cast(m_opaque_ptr), name ? name : ""); return name; } diff --git a/source/API/SBSymbolContext.cpp b/source/API/SBSymbolContext.cpp index 479b0f75bfe9..481fa1a1d1a2 100644 --- a/source/API/SBSymbolContext.cpp +++ b/source/API/SBSymbolContext.cpp @@ -101,8 +101,9 @@ SBSymbolContext::GetModule () { SBStream sstr; sb_module.GetDescription (sstr); - log->Printf ("SBSymbolContext(%p)::GetModule () => SBModule(%p): %s", - m_opaque_ap.get(), module_sp.get(), sstr.GetData()); + log->Printf ("SBSymbolContext(%p)::GetModule () => SBModule(%p): %s", + static_cast(m_opaque_ap.get()), + static_cast(module_sp.get()), sstr.GetData()); } return sb_module; @@ -120,15 +121,16 @@ SBSymbolContext::GetFunction () Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); Function *function = NULL; - + if (m_opaque_ap.get()) function = m_opaque_ap->function; SBFunction sb_function (function); if (log) - log->Printf ("SBSymbolContext(%p)::GetFunction () => SBFunction(%p)", - m_opaque_ap.get(), function); + log->Printf ("SBSymbolContext(%p)::GetFunction () => SBFunction(%p)", + static_cast(m_opaque_ap.get()), + static_cast(function)); return sb_function; } @@ -150,8 +152,9 @@ SBSymbolContext::GetLineEntry () if (log) { - log->Printf ("SBSymbolContext(%p)::GetLineEntry () => SBLineEntry(%p)", - m_opaque_ap.get(), sb_line_entry.get()); + log->Printf ("SBSymbolContext(%p)::GetLineEntry () => SBLineEntry(%p)", + static_cast(m_opaque_ap.get()), + static_cast(sb_line_entry.get())); } return sb_line_entry; @@ -163,19 +166,18 @@ SBSymbolContext::GetSymbol () Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); Symbol *symbol = NULL; - + if (m_opaque_ap.get()) symbol = m_opaque_ap->symbol; SBSymbol sb_symbol (symbol); if (log) - { - log->Printf ("SBSymbolContext(%p)::GetSymbol () => SBSymbol(%p)", - m_opaque_ap.get(), symbol); - } + log->Printf ("SBSymbolContext(%p)::GetSymbol () => SBSymbol(%p)", + static_cast(m_opaque_ap.get()), + static_cast(symbol)); - return sb_symbol; + return sb_symbol; } void diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp index 224349c0bce6..3d5828c5fe00 100644 --- a/source/API/SBTarget.cpp +++ b/source/API/SBTarget.cpp @@ -120,6 +120,18 @@ 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); +} + uint32_t SBLaunchInfo::GetNumArguments () { @@ -268,6 +280,29 @@ 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()) @@ -541,10 +576,9 @@ SBTarget::GetProcess () Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - { - log->Printf ("SBTarget(%p)::GetProcess () => SBProcess(%p)", - target_sp.get(), process_sp.get()); - } + log->Printf ("SBTarget(%p)::GetProcess () => SBProcess(%p)", + static_cast(target_sp.get()), + static_cast(process_sp.get())); return sb_process; } @@ -641,19 +675,15 @@ SBTarget::Launch TargetSP target_sp(GetSP()); if (log) - { log->Printf ("SBTarget(%p)::Launch (argv=%p, envp=%p, stdin=%s, stdout=%s, stderr=%s, working-dir=%s, launch_flags=0x%x, stop_at_entry=%i, &error (%p))...", - target_sp.get(), - argv, - envp, - stdin_path ? stdin_path : "NULL", - stdout_path ? stdout_path : "NULL", - stderr_path ? stderr_path : "NULL", + static_cast(target_sp.get()), + static_cast(argv), static_cast(envp), + stdin_path ? stdin_path : "NULL", + stdout_path ? stdout_path : "NULL", + stderr_path ? stderr_path : "NULL", working_directory ? working_directory : "NULL", - launch_flags, - stop_at_entry, - error.get()); - } + launch_flags, stop_at_entry, + static_cast(error.get())); if (target_sp) { @@ -667,17 +697,17 @@ SBTarget::Launch if (process_sp) { state = process_sp->GetState(); - + if (process_sp->IsAlive() && state != eStateConnected) - { + { if (state == eStateAttaching) error.SetErrorString ("process attach is in progress"); else error.SetErrorString ("a process is already being debugged"); return sb_process; - } + } } - + if (state == eStateConnected) { // If we are already connected, then we have already specified the @@ -694,7 +724,7 @@ SBTarget::Launch launch_flags |= eLaunchFlagDisableSTDIO; ProcessLaunchInfo launch_info (stdin_path, stdout_path, stderr_path, working_directory, launch_flags); - + Module *exe_module = target_sp->GetExecutableModulePointer(); if (exe_module) launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true); @@ -717,10 +747,9 @@ SBTarget::Launch log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); if (log) - { - log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)", - target_sp.get(), sb_process.GetSP().get()); - } + log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)", + static_cast(target_sp.get()), + static_cast(sb_process.GetSP().get())); return sb_process; } @@ -729,46 +758,48 @@ SBProcess SBTarget::Launch (SBLaunchInfo &sb_launch_info, SBError& error) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + SBProcess sb_process; TargetSP target_sp(GetSP()); - + if (log) - { - log->Printf ("SBTarget(%p)::Launch (launch_info, error)...", target_sp.get()); - } - + log->Printf ("SBTarget(%p)::Launch (launch_info, error)...", + static_cast(target_sp.get())); + if (target_sp) { Mutex::Locker api_locker (target_sp->GetAPIMutex()); StateType state = eStateInvalid; { - ProcessSP process_sp = target_sp->GetProcessSP(); - if (process_sp) - { - state = process_sp->GetState(); - - if (process_sp->IsAlive() && state != eStateConnected) - { - if (state == eStateAttaching) - error.SetErrorString ("process attach is in progress"); - else - error.SetErrorString ("a process is already being debugged"); - return sb_process; - } - } + ProcessSP process_sp = target_sp->GetProcessSP(); + if (process_sp) + { + state = process_sp->GetState(); + + if (process_sp->IsAlive() && state != eStateConnected) + { + if (state == eStateAttaching) + error.SetErrorString ("process attach is in progress"); + else + error.SetErrorString ("a process is already being debugged"); + return sb_process; + } + } } lldb_private::ProcessLaunchInfo &launch_info = sb_launch_info.ref(); - Module *exe_module = target_sp->GetExecutableModulePointer(); - if (exe_module) - launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true); + if (!launch_info.GetExecutableFile()) + { + Module *exe_module = target_sp->GetExecutableModulePointer(); + if (exe_module) + launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true); + } const ArchSpec &arch_spec = target_sp->GetArchitecture(); if (arch_spec.IsValid()) launch_info.GetArchitecture () = arch_spec; - + error.SetError (target_sp->Launch (target_sp->GetDebugger().GetListener(), launch_info)); sb_process.SetSP(target_sp->GetProcessSP()); } @@ -776,14 +807,13 @@ SBTarget::Launch (SBLaunchInfo &sb_launch_info, SBError& error) { error.SetErrorString ("SBTarget is invalid"); } - + log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); if (log) - { log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)", - target_sp.get(), sb_process.GetSP().get()); - } - + static_cast(target_sp.get()), + static_cast(sb_process.GetSP().get())); + return sb_process; } @@ -791,41 +821,39 @@ lldb::SBProcess SBTarget::Attach (SBAttachInfo &sb_attach_info, SBError& error) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + SBProcess sb_process; ProcessSP process_sp; TargetSP target_sp(GetSP()); - + if (log) - { - log->Printf ("SBTarget(%p)::Attach (sb_attach_info, error)...", target_sp.get()); - } - + log->Printf ("SBTarget(%p)::Attach (sb_attach_info, error)...", + static_cast(target_sp.get())); + if (target_sp) { Mutex::Locker api_locker (target_sp->GetAPIMutex()); - + StateType state = eStateInvalid; process_sp = target_sp->GetProcessSP(); if (process_sp) { state = process_sp->GetState(); - + if (process_sp->IsAlive() && state != eStateConnected) - { + { if (state == eStateAttaching) error.SetErrorString ("process attach is in progress"); else error.SetErrorString ("a process is already being debugged"); if (log) - { log->Printf ("SBTarget(%p)::Attach (...) => error %s", - target_sp.get(), error.GetCString()); - } + static_cast(target_sp.get()), + error.GetCString()); return sb_process; - } + } } - + if (state != eStateConnected) process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL); @@ -850,7 +878,7 @@ SBTarget::Attach (SBAttachInfo &sb_attach_info, SBError& error) if (log) { log->Printf ("SBTarget(%p)::Attach (...) => error %s", - target_sp.get(), error.GetCString()); + static_cast(target_sp.get()), error.GetCString()); } return sb_process; } @@ -875,13 +903,12 @@ SBTarget::Attach (SBAttachInfo &sb_attach_info, SBError& error) { error.SetErrorString ("SBTarget is invalid"); } - + if (log) - { log->Printf ("SBTarget(%p)::Attach (...) => SBProcess(%p)", - target_sp.get(), process_sp.get()); - } - + static_cast(target_sp.get()), + static_cast(process_sp.get())); + return sb_process; } @@ -913,10 +940,9 @@ SBTarget::AttachToProcessWithID TargetSP target_sp(GetSP()); if (log) - { - log->Printf ("SBTarget(%p)::AttachToProcessWithID (listener, pid=%" PRId64 ", error)...", target_sp.get(), pid); - } - + log->Printf ("SBTarget(%p)::AttachToProcessWithID (listener, pid=%" PRId64 ", error)...", + static_cast(target_sp.get()), pid); + if (target_sp) { Mutex::Locker api_locker (target_sp->GetAPIMutex()); @@ -926,15 +952,15 @@ SBTarget::AttachToProcessWithID if (process_sp) { state = process_sp->GetState(); - + if (process_sp->IsAlive() && state != eStateConnected) - { + { if (state == eStateAttaching) error.SetErrorString ("process attach is in progress"); else error.SetErrorString ("a process is already being debugged"); return sb_process; - } + } } if (state == eStateConnected) @@ -958,10 +984,10 @@ SBTarget::AttachToProcessWithID if (process_sp) { sb_process.SetSP (process_sp); - + ProcessAttachInfo attach_info; attach_info.SetProcessID (pid); - + PlatformSP platform_sp = target_sp->GetPlatform(); ProcessInstanceInfo instance_info; if (platform_sp->GetProcessInfo(pid, instance_info)) @@ -986,12 +1012,11 @@ SBTarget::AttachToProcessWithID { error.SetErrorString ("SBTarget is invalid"); } - + if (log) - { log->Printf ("SBTarget(%p)::AttachToProcessWithID (...) => SBProcess(%p)", - target_sp.get(), process_sp.get()); - } + static_cast(target_sp.get()), + static_cast(process_sp.get())); return sb_process; } @@ -1005,16 +1030,16 @@ SBTarget::AttachToProcessWithName ) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + SBProcess sb_process; ProcessSP process_sp; TargetSP target_sp(GetSP()); - + if (log) - { - log->Printf ("SBTarget(%p)::AttachToProcessWithName (listener, name=%s, wait_for=%s, error)...", target_sp.get(), name, wait_for ? "true" : "false"); - } - + log->Printf ("SBTarget(%p)::AttachToProcessWithName (listener, name=%s, wait_for=%s, error)...", + static_cast(target_sp.get()), name, + wait_for ? "true" : "false"); + if (name && target_sp) { Mutex::Locker api_locker (target_sp->GetAPIMutex()); @@ -1024,17 +1049,17 @@ SBTarget::AttachToProcessWithName if (process_sp) { state = process_sp->GetState(); - + if (process_sp->IsAlive() && state != eStateConnected) - { + { if (state == eStateAttaching) error.SetErrorString ("process attach is in progress"); else error.SetErrorString ("a process is already being debugged"); return sb_process; - } + } } - + if (state == eStateConnected) { // If we are already connected, then we have already specified the @@ -1078,12 +1103,11 @@ SBTarget::AttachToProcessWithName { error.SetErrorString ("SBTarget is invalid"); } - + if (log) - { log->Printf ("SBTarget(%p)::AttachToPorcessWithName (...) => SBProcess(%p)", - target_sp.get(), process_sp.get()); - } + static_cast(target_sp.get()), + static_cast(process_sp.get())); return sb_process; } @@ -1101,12 +1125,11 @@ SBTarget::ConnectRemote SBProcess sb_process; ProcessSP process_sp; TargetSP target_sp(GetSP()); - + if (log) - { - log->Printf ("SBTarget(%p)::ConnectRemote (listener, url=%s, plugin_name=%s, error)...", target_sp.get(), url, plugin_name); - } - + log->Printf ("SBTarget(%p)::ConnectRemote (listener, url=%s, plugin_name=%s, error)...", + static_cast(target_sp.get()), url, plugin_name); + if (target_sp) { Mutex::Locker api_locker (target_sp->GetAPIMutex()); @@ -1114,8 +1137,7 @@ SBTarget::ConnectRemote process_sp = target_sp->CreateProcess (listener.ref(), plugin_name, NULL); else process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), plugin_name, NULL); - - + if (process_sp) { sb_process.SetSP (process_sp); @@ -1130,12 +1152,11 @@ SBTarget::ConnectRemote { error.SetErrorString ("SBTarget is invalid"); } - + if (log) - { log->Printf ("SBTarget(%p)::ConnectRemote (...) => SBProcess(%p)", - target_sp.get(), process_sp.get()); - } + static_cast(target_sp.get()), + static_cast(process_sp.get())); return sb_process; } @@ -1155,8 +1176,9 @@ SBTarget::GetExecutable () Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { - log->Printf ("SBTarget(%p)::GetExecutable () => SBFileSpec(%p)", - target_sp.get(), exe_file_spec.get()); + log->Printf ("SBTarget(%p)::GetExecutable () => SBFileSpec(%p)", + static_cast(target_sp.get()), + static_cast(exe_file_spec.get())); } return exe_file_spec; @@ -1258,7 +1280,7 @@ SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec, if (target_sp && line != 0) { Mutex::Locker api_locker (target_sp->GetAPIMutex()); - + const LazyBool check_inlines = eLazyBoolCalculate; const LazyBool skip_prologue = eLazyBoolCalculate; const bool internal = false; @@ -1272,12 +1294,9 @@ SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec, sb_bp.GetDescription (sstr); char path[PATH_MAX]; sb_file_spec->GetPath (path, sizeof(path)); - log->Printf ("SBTarget(%p)::BreakpointCreateByLocation ( %s:%u ) => SBBreakpoint(%p): %s", - target_sp.get(), - path, - line, - sb_bp.get(), - sstr.GetData()); + log->Printf ("SBTarget(%p)::BreakpointCreateByLocation ( %s:%u ) => SBBreakpoint(%p): %s", + static_cast(target_sp.get()), path, line, + static_cast(sb_bp.get()), sstr.GetData()); } return sb_bp; @@ -1294,7 +1313,7 @@ SBTarget::BreakpointCreateByName (const char *symbol_name, if (target_sp.get()) { Mutex::Locker api_locker (target_sp->GetAPIMutex()); - + const bool internal = false; const bool hardware = false; const LazyBool skip_prologue = eLazyBoolCalculate; @@ -1309,12 +1328,11 @@ SBTarget::BreakpointCreateByName (const char *symbol_name, *sb_bp = target_sp->CreateBreakpoint (NULL, NULL, symbol_name, eFunctionNameTypeAuto, skip_prologue, internal, hardware); } } - + if (log) - { - log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", module=\"%s\") => SBBreakpoint(%p)", - target_sp.get(), symbol_name, module_name, sb_bp.get()); - } + log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", module=\"%s\") => SBBreakpoint(%p)", + static_cast(target_sp.get()), symbol_name, + module_name, static_cast(sb_bp.get())); return sb_bp; } @@ -1352,12 +1370,11 @@ SBTarget::BreakpointCreateByName (const char *symbol_name, internal, hardware); } - + if (log) - { - log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", name_type: %d) => SBBreakpoint(%p)", - target_sp.get(), symbol_name, name_type_mask, sb_bp.get()); - } + log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", name_type: %d) => SBBreakpoint(%p)", + static_cast(target_sp.get()), symbol_name, + name_type_mask, static_cast(sb_bp.get())); return sb_bp; } @@ -1388,10 +1405,11 @@ SBTarget::BreakpointCreateByNames (const char *symbol_names[], internal, hardware); } - + if (log) { - log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbols={", target_sp.get()); + log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbols={", + static_cast(target_sp.get())); for (uint32_t i = 0 ; i < num_names; i++) { char sep; @@ -1403,9 +1421,9 @@ SBTarget::BreakpointCreateByNames (const char *symbol_names[], log->Printf ("\"%s\"%c ", symbol_names[i], sep); else log->Printf ("\"\"%c ", sep); - } - log->Printf ("name_type: %d) => SBBreakpoint(%p)", name_type_mask, sb_bp.get()); + log->Printf ("name_type: %d) => SBBreakpoint(%p)", name_type_mask, + static_cast(sb_bp.get())); } return sb_bp; @@ -1426,12 +1444,12 @@ SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const bool internal = false; const bool hardware = false; const LazyBool skip_prologue = eLazyBoolCalculate; - + if (module_name && module_name[0]) { FileSpecList module_spec_list; module_spec_list.Append (FileSpec (module_name, false)); - + *sb_bp = target_sp->CreateFuncRegexBreakpoint (&module_spec_list, NULL, regexp, skip_prologue, internal, hardware); } else @@ -1441,10 +1459,9 @@ SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, } if (log) - { - log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)", - target_sp.get(), symbol_name_regex, module_name, sb_bp.get()); - } + log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)", + static_cast(target_sp.get()), symbol_name_regex, + module_name, static_cast(sb_bp.get())); return sb_bp; } @@ -1465,15 +1482,14 @@ SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const bool internal = false; const bool hardware = false; const LazyBool skip_prologue = eLazyBoolCalculate; - + *sb_bp = target_sp->CreateFuncRegexBreakpoint (module_list.get(), comp_unit_list.get(), regexp, skip_prologue, internal, hardware); } if (log) - { - log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\") => SBBreakpoint(%p)", - target_sp.get(), symbol_name_regex, sb_bp.get()); - } + log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\") => SBBreakpoint(%p)", + static_cast(target_sp.get()), symbol_name_regex, + static_cast(sb_bp.get())); return sb_bp; } @@ -1491,11 +1507,12 @@ SBTarget::BreakpointCreateByAddress (addr_t address) const bool hardware = false; *sb_bp = target_sp->CreateBreakpoint (address, false, hardware); } - + if (log) - { - log->Printf ("SBTarget(%p)::BreakpointCreateByAddress (address=%" PRIu64 ") => SBBreakpoint(%p)", target_sp.get(), (uint64_t) address, sb_bp.get()); - } + log->Printf ("SBTarget(%p)::BreakpointCreateByAddress (address=%" PRIu64 ") => SBBreakpoint(%p)", + static_cast(target_sp.get()), + static_cast(address), + static_cast(sb_bp.get())); return sb_bp; } @@ -1516,12 +1533,12 @@ SBTarget::BreakpointCreateBySourceRegex (const char *source_regex, FileSpecList source_file_spec_list; const bool hardware = false; source_file_spec_list.Append (source_file.ref()); - + if (module_name && module_name[0]) { FileSpecList module_spec_list; module_spec_list.Append (FileSpec (module_name, false)); - + *sb_bp = target_sp->CreateSourceRegexBreakpoint (&module_spec_list, &source_file_spec_list, regexp, false, hardware); } else @@ -1534,8 +1551,9 @@ SBTarget::BreakpointCreateBySourceRegex (const char *source_regex, { char path[PATH_MAX]; source_file->GetPath (path, sizeof(path)); - log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\", file=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)", - target_sp.get(), source_regex, path, module_name, sb_bp.get()); + log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\", file=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)", + static_cast(target_sp.get()), source_regex, path, + module_name, static_cast(sb_bp.get())); } return sb_bp; @@ -1559,10 +1577,9 @@ SBTarget::BreakpointCreateBySourceRegex (const char *source_regex, } if (log) - { - log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\") => SBBreakpoint(%p)", - target_sp.get(), source_regex, sb_bp.get()); - } + log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\") => SBBreakpoint(%p)", + static_cast(target_sp.get()), source_regex, + static_cast(sb_bp.get())); return sb_bp; } @@ -1584,14 +1601,11 @@ SBTarget::BreakpointCreateForException (lldb::LanguageType language, } if (log) - { - log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (Language: %s, catch: %s throw: %s) => SBBreakpoint(%p)", - target_sp.get(), + log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (Language: %s, catch: %s throw: %s) => SBBreakpoint(%p)", + static_cast(target_sp.get()), LanguageRuntime::GetNameForLanguageType(language), - catch_bp ? "on" : "off", - throw_bp ? "on" : "off", - sb_bp.get()); - } + catch_bp ? "on" : "off", throw_bp ? "on" : "off", + static_cast(sb_bp.get())); return sb_bp; } @@ -1635,9 +1649,9 @@ SBTarget::BreakpointDelete (break_id_t bp_id) } if (log) - { - log->Printf ("SBTarget(%p)::BreakpointDelete (bp_id=%d) => %i", target_sp.get(), (uint32_t) bp_id, result); - } + log->Printf ("SBTarget(%p)::BreakpointDelete (bp_id=%d) => %i", + static_cast(target_sp.get()), + static_cast(bp_id), result); return result; } @@ -1656,10 +1670,10 @@ SBTarget::FindBreakpointByID (break_id_t bp_id) } if (log) - { - log->Printf ("SBTarget(%p)::FindBreakpointByID (bp_id=%d) => SBBreakpoint(%p)", - target_sp.get(), (uint32_t) bp_id, sb_breakpoint.get()); - } + log->Printf ("SBTarget(%p)::FindBreakpointByID (bp_id=%d) => SBBreakpoint(%p)", + static_cast(target_sp.get()), + static_cast(bp_id), + static_cast(sb_breakpoint.get())); return sb_breakpoint; } @@ -1744,9 +1758,9 @@ SBTarget::DeleteWatchpoint (watch_id_t wp_id) } if (log) - { - log->Printf ("SBTarget(%p)::WatchpointDelete (wp_id=%d) => %i", target_sp.get(), (uint32_t) wp_id, result); - } + log->Printf ("SBTarget(%p)::WatchpointDelete (wp_id=%d) => %i", + static_cast(target_sp.get()), + static_cast(wp_id), result); return result; } @@ -1769,10 +1783,10 @@ SBTarget::FindWatchpointByID (lldb::watch_id_t wp_id) } if (log) - { - log->Printf ("SBTarget(%p)::FindWatchpointByID (bp_id=%d) => SBWatchpoint(%p)", - target_sp.get(), (uint32_t) wp_id, watchpoint_sp.get()); - } + log->Printf ("SBTarget(%p)::FindWatchpointByID (bp_id=%d) => SBWatchpoint(%p)", + static_cast(target_sp.get()), + static_cast(wp_id), + static_cast(watchpoint_sp.get())); return sb_watchpoint; } @@ -1781,7 +1795,7 @@ lldb::SBWatchpoint SBTarget::WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write, SBError &error) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + SBWatchpoint sb_watchpoint; lldb::WatchpointSP watchpoint_sp; TargetSP target_sp(GetSP()); @@ -1798,7 +1812,7 @@ SBTarget::WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write, S error.SetErrorString("Can't create a watchpoint that is neither read nor write."); return sb_watchpoint; } - + // Target::CreateWatchpoint() is thread safe. Error cw_error; // This API doesn't take in a type, so we can't figure out what it is. @@ -1807,13 +1821,13 @@ SBTarget::WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write, S error.SetError(cw_error); sb_watchpoint.SetSP (watchpoint_sp); } - + if (log) - { log->Printf ("SBTarget(%p)::WatchAddress (addr=0x%" PRIx64 ", 0x%u) => SBWatchpoint(%p)", - target_sp.get(), addr, (uint32_t) size, watchpoint_sp.get()); - } - + static_cast(target_sp.get()), addr, + static_cast(size), + static_cast(watchpoint_sp.get())); + return sb_watchpoint; } @@ -1860,7 +1874,7 @@ SBTarget::CreateValueFromAddress (const char *name, SBAddress addr, SBType type) if (pointer_ast_type) { lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t))); - + ExecutionContext exe_ctx (ExecutionContextRef(ExecutionContext(m_opaque_sp.get(),false))); ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), pointer_ast_type, @@ -1868,7 +1882,7 @@ SBTarget::CreateValueFromAddress (const char *name, SBAddress addr, SBType type) buffer, exe_ctx.GetByteOrder(), exe_ctx.GetAddressByteSize())); - + if (ptr_result_valobj_sp) { ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress); @@ -1884,9 +1898,12 @@ SBTarget::CreateValueFromAddress (const char *name, SBAddress addr, SBType type) if (log) { if (new_value_sp) - log->Printf ("SBTarget(%p)::CreateValueFromAddress => \"%s\"", m_opaque_sp.get(), new_value_sp->GetName().AsCString()); + log->Printf ("SBTarget(%p)::CreateValueFromAddress => \"%s\"", + static_cast(m_opaque_sp.get()), + new_value_sp->GetName().AsCString()); else - log->Printf ("SBTarget(%p)::CreateValueFromAddress => NULL", m_opaque_sp.get()); + log->Printf ("SBTarget(%p)::CreateValueFromAddress => NULL", + static_cast(m_opaque_sp.get())); } return sb_value; } @@ -1981,7 +1998,8 @@ SBTarget::GetNumModules () const } if (log) - log->Printf ("SBTarget(%p)::GetNumModules () => %d", target_sp.get(), num); + log->Printf ("SBTarget(%p)::GetNumModules () => %d", + static_cast(target_sp.get()), num); return num; } @@ -1992,7 +2010,8 @@ SBTarget::Clear () Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBTarget(%p)::Clear ()", m_opaque_sp.get()); + log->Printf ("SBTarget(%p)::Clear ()", + static_cast(m_opaque_sp.get())); m_opaque_sp.reset(); } @@ -2063,10 +2082,9 @@ SBTarget::GetModuleAtIndex (uint32_t idx) } if (log) - { - log->Printf ("SBTarget(%p)::GetModuleAtIndex (idx=%d) => SBModule(%p)", - target_sp.get(), idx, module_sp.get()); - } + log->Printf ("SBTarget(%p)::GetModuleAtIndex (idx=%d) => SBModule(%p)", + static_cast(target_sp.get()), idx, + static_cast(module_sp.get())); return sb_module; } @@ -2088,10 +2106,11 @@ SBTarget::GetBroadcaster () const TargetSP target_sp(GetSP()); SBBroadcaster broadcaster(target_sp.get(), false); - + if (log) - log->Printf ("SBTarget(%p)::GetBroadcaster () => SBBroadcaster(%p)", - target_sp.get(), broadcaster.get()); + log->Printf ("SBTarget(%p)::GetBroadcaster () => SBBroadcaster(%p)", + static_cast(target_sp.get()), + static_cast(broadcaster.get())); return broadcaster; } @@ -2432,10 +2451,6 @@ SBTarget::SetSectionLoadAddress (lldb::SBSection section, else { ProcessSP process_sp (target_sp->GetProcessSP()); - uint32_t stop_id = 0; - if (process_sp) - stop_id = process_sp->GetStopID(); - if (target_sp->SetSectionLoadAddress (section_sp, section_base_addr)) { // Flush info in the process (stack frames, etc) @@ -2468,10 +2483,6 @@ SBTarget::ClearSectionLoadAddress (lldb::SBSection section) else { ProcessSP process_sp (target_sp->GetProcessSP()); - uint32_t stop_id = 0; - if (process_sp) - stop_id = process_sp->GetStopID(); - if (target_sp->SetSectionUnloaded (section.GetSP())) { // Flush info in the process (stack frames, etc) @@ -2547,9 +2558,6 @@ SBTarget::ClearModuleLoadAddress (lldb::SBModule module) if (section_list) { ProcessSP process_sp (target_sp->GetProcessSP()); - uint32_t stop_id = 0; - if (process_sp) - stop_id = process_sp->GetStopID(); bool changed = false; const size_t num_sections = section_list->GetSize(); @@ -2557,7 +2565,7 @@ SBTarget::ClearModuleLoadAddress (lldb::SBModule module) { SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx)); if (section_sp) - changed |= target_sp->SetSectionUnloaded (section_sp) > 0; + changed |= target_sp->SetSectionUnloaded (section_sp); } if (changed) { @@ -2619,7 +2627,7 @@ SBTarget::EvaluateExpression (const char *expr, const SBExpressionOptions &optio Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); Log * expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); SBValue expr_result; - ExecutionResults exe_results = eExecutionSetupError; + ExpressionResults exe_results = eExpressionSetupError; ValueObjectSP expr_value_sp; TargetSP target_sp(GetSP()); StackFrame *frame = NULL; @@ -2631,16 +2639,16 @@ SBTarget::EvaluateExpression (const char *expr, const SBExpressionOptions &optio log->Printf ("SBTarget::EvaluateExpression called with an empty expression"); return expr_result; } - + Mutex::Locker api_locker (target_sp->GetAPIMutex()); ExecutionContext exe_ctx (m_opaque_sp.get()); - + if (log) log->Printf ("SBTarget()::EvaluateExpression (expr=\"%s\")...", expr); - + frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); - + if (target) { #ifdef LLDB_CONFIGURATION_DEBUG @@ -2669,17 +2677,14 @@ SBTarget::EvaluateExpression (const char *expr, const SBExpressionOptions &optio #ifndef LLDB_DISABLE_PYTHON if (expr_log) expr_log->Printf("** [SBTarget::EvaluateExpression] Expression result is %s, summary %s **", - expr_result.GetValue(), - expr_result.GetSummary()); - + expr_result.GetValue(), expr_result.GetSummary()); + if (log) log->Printf ("SBTarget(%p)::EvaluateExpression (expr=\"%s\") => SBValue(%p) (execution result=%d)", - frame, - expr, - expr_value_sp.get(), - exe_results); + static_cast(frame), expr, + static_cast(expr_value_sp.get()), exe_results); #endif - + return expr_result; } diff --git a/source/API/SBThread.cpp b/source/API/SBThread.cpp index 4170d5b230bb..a0bfa4313535 100644 --- a/source/API/SBThread.cpp +++ b/source/API/SBThread.cpp @@ -19,10 +19,12 @@ #include "lldb/Core/State.h" #include "lldb/Core/Stream.h" #include "lldb/Core/StreamFile.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Target/SystemRuntime.h" #include "lldb/Target/Thread.h" #include "lldb/Target/Process.h" +#include "lldb/Target/Queue.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Target/StopInfo.h" @@ -88,6 +90,42 @@ SBThread::~SBThread() { } +lldb::SBQueue +SBThread::GetQueue () const +{ + SBQueue sb_queue; + QueueSP queue_sp; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (exe_ctx.HasThreadScope()) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + queue_sp = exe_ctx.GetThreadPtr()->GetQueue(); + if (queue_sp) + { + sb_queue.SetQueue (queue_sp); + } + } + else + { + if (log) + log->Printf ("SBThread(%p)::GetQueueKind() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); + } + } + + if (log) + log->Printf ("SBThread(%p)::GetQueueKind () => SBQueue(%p)", + static_cast(exe_ctx.GetThreadPtr()), static_cast(queue_sp.get())); + + return sb_queue; +} + + bool SBThread::IsValid() const { @@ -120,12 +158,14 @@ SBThread::GetStopReason() else { if (log) - log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", exe_ctx.GetThreadPtr()); + log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); } } if (log) - log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(), + log->Printf ("SBThread(%p)::GetStopReason () => %s", + static_cast(exe_ctx.GetThreadPtr()), Thread::StopReasonAsCString (reason)); return reason; @@ -183,7 +223,8 @@ SBThread::GetStopReasonDataCount () { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", exe_ctx.GetThreadPtr()); + log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); } } return 0; @@ -226,7 +267,7 @@ SBThread::GetStopReasonDataAtIndex (uint32_t idx) BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index)); if (bp_loc_sp) { - if (bp_index & 1) + if (idx & 1) { // Odd idx, return the breakpoint location ID return bp_loc_sp->GetID(); @@ -257,7 +298,8 @@ SBThread::GetStopReasonDataAtIndex (uint32_t idx) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", exe_ctx.GetThreadPtr()); + log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); } } return 0; @@ -284,8 +326,9 @@ SBThread::GetStopDescription (char *dst, size_t dst_len) if (stop_desc) { if (log) - log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", - exe_ctx.GetThreadPtr(), stop_desc); + log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", + static_cast(exe_ctx.GetThreadPtr()), + stop_desc); if (dst) return ::snprintf (dst, dst_len, "%s", stop_desc); else @@ -362,19 +405,20 @@ SBThread::GetStopDescription (char *dst, size_t dst_len) default: break; } - + if (stop_desc && stop_desc[0]) { if (log) - log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", - exe_ctx.GetThreadPtr(), stop_desc); + log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", + static_cast(exe_ctx.GetThreadPtr()), + stop_desc); if (dst) return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte if (stop_desc_len == 0) stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte - + return stop_desc_len; } } @@ -384,7 +428,8 @@ SBThread::GetStopDescription (char *dst, size_t dst_len) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", exe_ctx.GetThreadPtr()); + log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); } } if (dst) @@ -414,16 +459,18 @@ SBThread::GetStopReturnValue () else { if (log) - log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", exe_ctx.GetThreadPtr()); + log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); } } - + if (log) - log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(), - return_valobj_sp.get() - ? return_valobj_sp->GetValueAsCString() - : ""); - + log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", + static_cast(exe_ctx.GetThreadPtr()), + return_valobj_sp.get() + ? return_valobj_sp->GetValueAsCString() + : ""); + return SBValue (return_valobj_sp); } @@ -469,12 +516,15 @@ SBThread::GetName () const else { if (log) - log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr()); + log->Printf ("SBThread(%p)::GetName() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); } } - + if (log) - log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL"); + log->Printf ("SBThread(%p)::GetName () => %s", + static_cast(exe_ctx.GetThreadPtr()), + name ? name : "NULL"); return name; } @@ -497,12 +547,15 @@ SBThread::GetQueueName () const else { if (log) - log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr()); + log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); } } - + if (log) - log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL"); + log->Printf ("SBThread(%p)::GetQueueName () => %s", + static_cast(exe_ctx.GetThreadPtr()), + name ? name : "NULL"); return name; } @@ -525,16 +578,86 @@ SBThread::GetQueueID () const else { if (log) - log->Printf ("SBThread(%p)::GetQueueID() => error: process is running", exe_ctx.GetThreadPtr()); + log->Printf ("SBThread(%p)::GetQueueID() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); } } - + if (log) - log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64, exe_ctx.GetThreadPtr(), id); + log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64, + static_cast(exe_ctx.GetThreadPtr()), id); return id; } +bool +SBThread::GetInfoItemByPathAsString (const char *path, SBStream &strm) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + bool success = false; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + if (exe_ctx.HasThreadScope()) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Thread *thread = exe_ctx.GetThreadPtr(); + StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo(); + if (info_root_sp) + { + StructuredData::ObjectSP node = info_root_sp->GetObjectForDotSeparatedPath (path); + if (node) + { + if (node->GetType() == StructuredData::Type::eTypeString) + { + strm.Printf ("%s", node->GetAsString()->GetValue().c_str()); + success = true; + } + if (node->GetType() == StructuredData::Type::eTypeInteger) + { + strm.Printf ("0x%" PRIx64, node->GetAsInteger()->GetValue()); + success = true; + } + if (node->GetType() == StructuredData::Type::eTypeFloat) + { + strm.Printf ("0x%f", node->GetAsFloat()->GetValue()); + success = true; + } + if (node->GetType() == StructuredData::Type::eTypeBoolean) + { + if (node->GetAsBoolean()->GetValue() == true) + strm.Printf ("true"); + else + strm.Printf ("false"); + success = true; + } + if (node->GetType() == StructuredData::Type::eTypeNull) + { + strm.Printf ("null"); + success = true; + } + } + } + } + else + { + if (log) + log->Printf ("SBThread(%p)::GetInfoItemByPathAsString() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); + } + } + + if (log) + log->Printf ("SBThread(%p)::GetInfoItemByPathAsString () => %s", + static_cast(exe_ctx.GetThreadPtr()), + strm.GetData()); + + return success; +} + + SBError SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan) { @@ -587,9 +710,10 @@ SBThread::StepOver (lldb::RunMode stop_other_threads) if (log) - log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(), + log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", + static_cast(exe_ctx.GetThreadPtr()), Thread::RunModeAsCString (stop_other_threads)); - + if (exe_ctx.HasThreadScope()) { Thread *thread = exe_ctx.GetThreadPtr(); @@ -601,17 +725,19 @@ SBThread::StepOver (lldb::RunMode stop_other_threads) { if (frame_sp->HasDebugInformation ()) { + const LazyBool avoid_no_debug = eLazyBoolCalculate; SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans, sc.line_entry.range, sc, - stop_other_threads); + stop_other_threads, + avoid_no_debug); } else { new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, - abort_other_plans, - stop_other_threads); + abort_other_plans, + stop_other_threads); } } @@ -636,10 +762,10 @@ SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads) if (log) log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')", - exe_ctx.GetThreadPtr(), + static_cast(exe_ctx.GetThreadPtr()), target_name? target_name: "", Thread::RunModeAsCString (stop_other_threads)); - + if (exe_ctx.HasThreadScope()) { bool abort_other_plans = false; @@ -650,22 +776,24 @@ SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads) if (frame_sp && frame_sp->HasDebugInformation ()) { - bool avoid_code_without_debug_info = true; + const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate; + const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate; SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans, sc.line_entry.range, sc, target_name, stop_other_threads, - avoid_code_without_debug_info); + step_in_avoids_code_without_debug_info, + step_out_avoids_code_without_debug_info); } else { new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, - abort_other_plans, - stop_other_threads); + abort_other_plans, + stop_other_threads); } - + // This returns an error, we should use it! ResumeNewPlan (exe_ctx, new_plan_sp.get()); } @@ -681,8 +809,9 @@ SBThread::StepOut () if (log) - log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr()); - + log->Printf ("SBThread(%p)::StepOut ()", + static_cast(exe_ctx.GetThreadPtr())); + if (exe_ctx.HasThreadScope()) { bool abort_other_plans = false; @@ -690,14 +819,16 @@ SBThread::StepOut () Thread *thread = exe_ctx.GetThreadPtr(); + const LazyBool avoid_no_debug = eLazyBoolCalculate; ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, - NULL, - false, - stop_other_threads, - eVoteYes, - eVoteNoOpinion, - 0)); - + NULL, + false, + stop_other_threads, + eVoteYes, + eVoteNoOpinion, + 0, + avoid_no_debug)); + // This returns an error, we should use it! ResumeNewPlan (exe_ctx, new_plan_sp.get()); } @@ -716,7 +847,10 @@ SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) { SBStream frame_desc_strm; sb_frame.GetDescription (frame_desc_strm); - log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData()); + log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", + static_cast(exe_ctx.GetThreadPtr()), + static_cast(frame_sp.get()), + frame_desc_strm.GetData()); } if (exe_ctx.HasThreadScope()) @@ -726,13 +860,13 @@ SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) Thread *thread = exe_ctx.GetThreadPtr(); ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, - NULL, - false, - stop_other_threads, - eVoteYes, + NULL, + false, + stop_other_threads, + eVoteYes, eVoteNoOpinion, frame_sp->GetFrameIndex())); - + // This returns an error, we should use it! ResumeNewPlan (exe_ctx, new_plan_sp.get()); } @@ -749,13 +883,14 @@ SBThread::StepInstruction (bool step_over) if (log) - log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over); - + log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", + static_cast(exe_ctx.GetThreadPtr()), step_over); + if (exe_ctx.HasThreadScope()) { Thread *thread = exe_ctx.GetThreadPtr(); ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true)); - + // This returns an error, we should use it! ResumeNewPlan (exe_ctx, new_plan_sp.get()); } @@ -771,8 +906,9 @@ SBThread::RunToAddress (lldb::addr_t addr) if (log) - log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", exe_ctx.GetThreadPtr(), addr); - + log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", + static_cast(exe_ctx.GetThreadPtr()), addr); + if (exe_ctx.HasThreadScope()) { bool abort_other_plans = false; @@ -783,7 +919,7 @@ SBThread::RunToAddress (lldb::addr_t addr) Thread *thread = exe_ctx.GetThreadPtr(); ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads)); - + // This returns an error, we should use it! ResumeNewPlan (exe_ctx, new_plan_sp.get()); } @@ -797,7 +933,7 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame, SBError sb_error; Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); char path[PATH_MAX]; - + Mutex::Locker api_locker; ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); @@ -808,11 +944,10 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame, SBStream frame_desc_strm; sb_frame.GetDescription (frame_desc_strm); sb_file_spec->GetPath (path, sizeof(path)); - log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", - exe_ctx.GetThreadPtr(), - frame_sp.get(), - frame_desc_strm.GetData(), - path, line); + log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", + static_cast(exe_ctx.GetThreadPtr()), + static_cast(frame_sp.get()), + frame_desc_strm.GetData(), path, line); } if (exe_ctx.HasThreadScope()) @@ -825,14 +960,14 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame, sb_error.SetErrorString("invalid line argument"); return sb_error; } - + if (!frame_sp) { frame_sp = thread->GetSelectedFrame (); if (!frame_sp) frame_sp = thread->GetStackFrameAtIndex (0); } - + SymbolContext frame_sc; if (!frame_sp) { @@ -845,13 +980,13 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame, eSymbolContextFunction | eSymbolContextLineEntry | eSymbolContextSymbol ); - + if (frame_sc.comp_unit == NULL) { sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex()); return sb_error; } - + FileSpec step_file_spec; if (sb_file_spec.IsValid()) { @@ -868,15 +1003,15 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame, return sb_error; } } - + // Grab the current function, then we will make sure the "until" address is // within the function. We discard addresses that are out of the current // function, and then if there are no addresses remaining, give an appropriate // error message. - + bool all_in_function = true; AddressRange fun_range = frame_sc.function->GetAddressRange(); - + std::vector step_over_until_addrs; const bool abort_other_plans = false; const bool stop_other_threads = false; @@ -908,7 +1043,7 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame, } } } - + if (step_over_until_addrs.empty()) { if (all_in_function) @@ -947,7 +1082,9 @@ SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line) ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); if (log) - log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)", exe_ctx.GetThreadPtr(), file_spec->GetPath().c_str(), line); + log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)", + static_cast(exe_ctx.GetThreadPtr()), + file_spec->GetPath().c_str(), line); if (!exe_ctx.HasThreadScope()) { @@ -966,7 +1103,7 @@ SBError SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value) { SBError sb_error; - + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); Mutex::Locker api_locker; @@ -974,14 +1111,16 @@ SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value) if (log) - log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", exe_ctx.GetThreadPtr(), frame.GetFrameID()); - + log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", + static_cast(exe_ctx.GetThreadPtr()), + frame.GetFrameID()); + if (exe_ctx.HasThreadScope()) { Thread *thread = exe_ctx.GetThreadPtr(); sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP())); } - + return sb_error; } @@ -1003,11 +1142,13 @@ SBThread::Suspend() else { if (log) - log->Printf ("SBThread(%p)::Suspend() => error: process is running", exe_ctx.GetThreadPtr()); + log->Printf ("SBThread(%p)::Suspend() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); } } if (log) - log->Printf ("SBThread(%p)::Suspend() => %i", exe_ctx.GetThreadPtr(), result); + log->Printf ("SBThread(%p)::Suspend() => %i", + static_cast(exe_ctx.GetThreadPtr()), result); return result; } @@ -1022,17 +1163,20 @@ SBThread::Resume () Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning); + const bool override_suspend = true; + exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend); result = true; } else { if (log) - log->Printf ("SBThread(%p)::Resume() => error: process is running", exe_ctx.GetThreadPtr()); + log->Printf ("SBThread(%p)::Resume() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); } } if (log) - log->Printf ("SBThread(%p)::Resume() => %i", exe_ctx.GetThreadPtr(), result); + log->Printf ("SBThread(%p)::Resume() => %i", + static_cast(exe_ctx.GetThreadPtr()), result); return result; } @@ -1070,8 +1214,10 @@ SBThread::GetProcess () { SBStream frame_desc_strm; sb_process.GetDescription (frame_desc_strm); - log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(), - sb_process.GetSP().get(), frame_desc_strm.GetData()); + log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", + static_cast(exe_ctx.GetThreadPtr()), + static_cast(sb_process.GetSP().get()), + frame_desc_strm.GetData()); } return sb_process; @@ -1096,12 +1242,14 @@ SBThread::GetNumFrames () else { if (log) - log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", exe_ctx.GetThreadPtr()); + log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); } } if (log) - log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames); + log->Printf ("SBThread(%p)::GetNumFrames () => %u", + static_cast(exe_ctx.GetThreadPtr()), num_frames); return num_frames; } @@ -1127,7 +1275,8 @@ SBThread::GetFrameAtIndex (uint32_t idx) else { if (log) - log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", exe_ctx.GetThreadPtr()); + log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); } } @@ -1135,8 +1284,10 @@ SBThread::GetFrameAtIndex (uint32_t idx) { SBStream frame_desc_strm; sb_frame.GetDescription (frame_desc_strm); - log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", - exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData()); + log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", + static_cast(exe_ctx.GetThreadPtr()), idx, + static_cast(frame_sp.get()), + frame_desc_strm.GetData()); } return sb_frame; @@ -1163,7 +1314,8 @@ SBThread::GetSelectedFrame () else { if (log) - log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr()); + log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); } } @@ -1171,8 +1323,10 @@ SBThread::GetSelectedFrame () { SBStream frame_desc_strm; sb_frame.GetDescription (frame_desc_strm); - log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", - exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData()); + log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", + static_cast(exe_ctx.GetThreadPtr()), + static_cast(frame_sp.get()), + frame_desc_strm.GetData()); } return sb_frame; @@ -1204,7 +1358,8 @@ SBThread::SetSelectedFrame (uint32_t idx) else { if (log) - log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr()); + log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); } } @@ -1212,8 +1367,10 @@ SBThread::SetSelectedFrame (uint32_t idx) { SBStream frame_desc_strm; sb_frame.GetDescription (frame_desc_strm); - log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", - exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData()); + log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", + static_cast(exe_ctx.GetThreadPtr()), idx, + static_cast(frame_sp.get()), + frame_desc_strm.GetData()); } return sb_frame; } @@ -1316,7 +1473,11 @@ SBThread::GetExtendedBacktraceThread (const char *type) const char *queue_name = new_thread_sp->GetQueueName(); if (queue_name == NULL) queue_name = ""; - log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread created (%p) with queue_id 0x%" PRIx64 " queue name '%s'", exe_ctx.GetThreadPtr(), new_thread_sp.get(), new_thread_sp->GetQueueID(), queue_name); + log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread created (%p) with queue_id 0x%" PRIx64 " queue name '%s'", + static_cast(exe_ctx.GetThreadPtr()), + static_cast(new_thread_sp.get()), + new_thread_sp->GetQueueID(), + queue_name); } } } @@ -1326,10 +1487,14 @@ SBThread::GetExtendedBacktraceThread (const char *type) else { if (log) - log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running", exe_ctx.GetThreadPtr()); + log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running", + static_cast(exe_ctx.GetThreadPtr())); } } + if (log && sb_origin_thread.IsValid() == false) + log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread", + static_cast(exe_ctx.GetThreadPtr())); return sb_origin_thread; } @@ -1341,3 +1506,12 @@ SBThread::GetExtendedBacktraceOriginatingIndexID () return thread_sp->GetExtendedBacktraceOriginatingIndexID(); return LLDB_INVALID_INDEX32; } + +bool +SBThread::SafeToCallFunctions () +{ + ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); + if (thread_sp) + return thread_sp->SafeToCallFunctions(); + return true; +} diff --git a/source/API/SBType.cpp b/source/API/SBType.cpp index 5ca7ddf3d813..064fb32c953f 100644 --- a/source/API/SBType.cpp +++ b/source/API/SBType.cpp @@ -9,6 +9,7 @@ #include "lldb/API/SBDefines.h" #include "lldb/API/SBType.h" +#include "lldb/API/SBTypeEnumMember.h" #include "lldb/API/SBStream.h" #include "lldb/Core/ConstString.h" #include "lldb/Core/Log.h" @@ -17,6 +18,8 @@ #include "lldb/Symbol/ClangASTType.h" #include "lldb/Symbol/Type.h" +#include "clang/AST/Decl.h" + using namespace lldb; using namespace lldb_private; using namespace clang; @@ -364,6 +367,27 @@ SBType::GetVirtualBaseClassAtIndex (uint32_t idx) return sb_type_member; } +SBTypeEnumMemberList +SBType::GetEnumMembers () +{ + SBTypeEnumMemberList sb_enum_member_list; + if (IsValid()) + { + const clang::EnumDecl *enum_decl = m_opaque_sp->GetClangASTType(true).GetFullyUnqualifiedType().GetAsEnumDecl(); + if (enum_decl) + { + clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos; + for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos) + { + SBTypeEnumMember enum_member; + enum_member.reset(new TypeEnumMemberImpl(*enum_pos, ClangASTType(m_opaque_sp->GetClangASTContext(true), enum_decl->getIntegerType()))); + sb_enum_member_list.Append(enum_member); + } + } + } + return sb_enum_member_list; +} + SBTypeMember SBType::GetFieldAtIndex (uint32_t idx) { @@ -414,6 +438,14 @@ SBType::GetName() return m_opaque_sp->GetName().GetCString(); } +const char * +SBType::GetDisplayTypeName () +{ + if (!IsValid()) + return ""; + return m_opaque_sp->GetDisplayTypeName().GetCString(); +} + lldb::TypeClass SBType::GetTypeClass () { diff --git a/source/API/SBTypeEnumMember.cpp b/source/API/SBTypeEnumMember.cpp new file mode 100644 index 000000000000..47c57dd213fb --- /dev/null +++ b/source/API/SBTypeEnumMember.cpp @@ -0,0 +1,192 @@ +//===-- SBTypeEnumMember.cpp ---------------------------------- -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/API/SBDefines.h" +#include "lldb/API/SBType.h" +#include "lldb/API/SBTypeEnumMember.h" +#include "lldb/API/SBStream.h" +#include "lldb/Core/Stream.h" +#include "lldb/Symbol/ClangASTType.h" +#include "lldb/Symbol/Type.h" + +using namespace lldb; +using namespace lldb_private; +using namespace clang; + +SBTypeEnumMember::SBTypeEnumMember() : + m_opaque_sp() +{ +} + +SBTypeEnumMember::~SBTypeEnumMember() +{ +} +SBTypeEnumMember::SBTypeEnumMember (const lldb::TypeEnumMemberImplSP &enum_member_sp) : + m_opaque_sp(enum_member_sp) +{ +} + +SBTypeEnumMember::SBTypeEnumMember (const SBTypeEnumMember& rhs) : + m_opaque_sp() +{ + if (this != &rhs) + { + if (rhs.IsValid()) + m_opaque_sp.reset(new TypeEnumMemberImpl(rhs.ref())); + } +} + +SBTypeEnumMember& +SBTypeEnumMember::operator = (const SBTypeEnumMember& rhs) +{ + if (this != &rhs) + { + if (rhs.IsValid()) + m_opaque_sp.reset(new TypeEnumMemberImpl(rhs.ref())); + } + return *this; +} + +bool +SBTypeEnumMember::IsValid() const +{ + return m_opaque_sp.get(); +} + +const char * +SBTypeEnumMember::GetName () +{ + if (m_opaque_sp.get()) + return m_opaque_sp->GetName().GetCString(); + return NULL; +} + +int64_t +SBTypeEnumMember::GetValueAsSigned() +{ + if (m_opaque_sp.get()) + return m_opaque_sp->GetValueAsSigned(); + return 0; +} + +uint64_t +SBTypeEnumMember::GetValueAsUnsigned() +{ + if (m_opaque_sp.get()) + return m_opaque_sp->GetValueAsUnsigned(); + return 0; +} + +SBType +SBTypeEnumMember::GetType () +{ + SBType sb_type; + if (m_opaque_sp.get()) + { + sb_type.SetSP(m_opaque_sp->GetIntegerType()); + } + return sb_type; + +} + +void +SBTypeEnumMember::reset(TypeEnumMemberImpl *type_member_impl) +{ + m_opaque_sp.reset(type_member_impl); +} + +TypeEnumMemberImpl & +SBTypeEnumMember::ref () +{ + if (m_opaque_sp.get() == NULL) + m_opaque_sp.reset (new TypeEnumMemberImpl()); + return *m_opaque_sp.get(); +} + +const TypeEnumMemberImpl & +SBTypeEnumMember::ref () const +{ + return *m_opaque_sp.get(); +} + + +SBTypeEnumMemberList::SBTypeEnumMemberList() : + m_opaque_ap(new TypeEnumMemberListImpl()) +{ +} + +SBTypeEnumMemberList::SBTypeEnumMemberList(const SBTypeEnumMemberList& rhs) : + m_opaque_ap(new TypeEnumMemberListImpl()) +{ + for (uint32_t i = 0, rhs_size = const_cast(rhs).GetSize(); i < rhs_size; i++) + Append(const_cast(rhs).GetTypeEnumMemberAtIndex(i)); +} + +bool +SBTypeEnumMemberList::IsValid () +{ + return (m_opaque_ap.get() != NULL); +} + +SBTypeEnumMemberList& +SBTypeEnumMemberList::operator = (const SBTypeEnumMemberList& rhs) +{ + if (this != &rhs) + { + m_opaque_ap.reset (new TypeEnumMemberListImpl()); + for (uint32_t i = 0, rhs_size = const_cast(rhs).GetSize(); i < rhs_size; i++) + Append(const_cast(rhs).GetTypeEnumMemberAtIndex(i)); + } + return *this; +} + +void +SBTypeEnumMemberList::Append (SBTypeEnumMember enum_member) +{ + if (enum_member.IsValid()) + m_opaque_ap->Append (enum_member.m_opaque_sp); +} + +SBTypeEnumMember +SBTypeEnumMemberList::GetTypeEnumMemberAtIndex(uint32_t index) +{ + if (m_opaque_ap.get()) + return SBTypeEnumMember(m_opaque_ap->GetTypeEnumMemberAtIndex(index)); + return SBTypeEnumMember(); +} + +uint32_t +SBTypeEnumMemberList::GetSize() +{ + return m_opaque_ap->GetSize(); +} + +SBTypeEnumMemberList::~SBTypeEnumMemberList() +{ +} + +bool +SBTypeEnumMember::GetDescription (lldb::SBStream &description, + lldb::DescriptionLevel description_level) +{ + Stream &strm = description.ref(); + + if (m_opaque_sp.get()) + { + if( m_opaque_sp->GetIntegerType()->GetDescription(strm, description_level) ) + { + strm.Printf(" %s", m_opaque_sp->GetName().GetCString()); + } + } + else + { + strm.PutCString ("No value"); + } + return true; +} diff --git a/source/API/SBUnixSignals.cpp b/source/API/SBUnixSignals.cpp new file mode 100644 index 000000000000..ca321d82fd60 --- /dev/null +++ b/source/API/SBUnixSignals.cpp @@ -0,0 +1,199 @@ +//===-- SBUnixSignals.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-defines.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/UnixSignals.h" +#include "lldb/Core/Log.h" + +#include "lldb/API/SBUnixSignals.h" + +using namespace lldb; +using namespace lldb_private; + +SBUnixSignals::SBUnixSignals () +{} + +SBUnixSignals::SBUnixSignals (const SBUnixSignals &rhs) : + m_opaque_wp(rhs.m_opaque_wp) +{ +} + +SBUnixSignals::SBUnixSignals (ProcessSP &process_sp) : + m_opaque_wp(process_sp) +{ +} + +const SBUnixSignals& +SBUnixSignals::operator = (const SBUnixSignals& rhs) +{ + if (this != &rhs) + m_opaque_wp = rhs.m_opaque_wp; + return *this; +} + +SBUnixSignals::~SBUnixSignals() +{ +} + +ProcessSP +SBUnixSignals::GetSP() const +{ + return m_opaque_wp.lock(); +} + +void +SBUnixSignals::SetSP (const ProcessSP &process_sp) +{ + m_opaque_wp = process_sp; +} + +void +SBUnixSignals::Clear () +{ + m_opaque_wp.reset(); +} + +bool +SBUnixSignals::IsValid() const +{ + return (bool) GetSP(); +} + +const char * +SBUnixSignals::GetSignalAsCString (int32_t signo) const +{ + ProcessSP process_sp(GetSP()); + if (process_sp) return process_sp->GetUnixSignals().GetSignalAsCString(signo); + return NULL; +} + +int32_t +SBUnixSignals::GetSignalNumberFromName (const char *name) const +{ + ProcessSP process_sp(GetSP()); + if (process_sp) return process_sp->GetUnixSignals().GetSignalNumberFromName(name); + return -1; +} + +bool +SBUnixSignals::GetShouldSuppress (int32_t signo) const +{ + ProcessSP process_sp(GetSP()); + if (process_sp) return process_sp->GetUnixSignals().GetShouldSuppress(signo); + return false; +} + +bool +SBUnixSignals::SetShouldSuppress (int32_t signo, bool value) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + ProcessSP process_sp(GetSP()); + + if (log) + { + log->Printf ("SBUnixSignals(%p)::SetShouldSuppress (signo=%d, value=%d)", + static_cast(process_sp.get()), + signo, + value); + } + + if (process_sp) return process_sp->GetUnixSignals().SetShouldSuppress(signo, value); + return false; +} + +bool +SBUnixSignals::GetShouldStop (int32_t signo) const +{ + ProcessSP process_sp(GetSP()); + if (process_sp) return process_sp->GetUnixSignals().GetShouldStop(signo); + return false; +} + +bool +SBUnixSignals::SetShouldStop (int32_t signo, bool value) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + ProcessSP process_sp(GetSP()); + + if (log) + { + log->Printf ("SBUnixSignals(%p)::SetShouldStop (signo=%d, value=%d)", + static_cast(process_sp.get()), + signo, + value); + } + + if (process_sp) return process_sp->GetUnixSignals().SetShouldStop(signo, value); + return false; +} + +bool +SBUnixSignals::GetShouldNotify (int32_t signo) const +{ + ProcessSP process_sp(GetSP()); + if (process_sp) return process_sp->GetUnixSignals().GetShouldNotify(signo); + return false; +} + +bool +SBUnixSignals::SetShouldNotify (int32_t signo, bool value) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + ProcessSP process_sp(GetSP()); + + if (log) + { + log->Printf ("SBUnixSignals(%p)::SetShouldNotify (signo=%d, value=%d)", + static_cast(process_sp.get()), + signo, + value); + } + + if (process_sp) return process_sp->GetUnixSignals().SetShouldNotify(signo, value); + return false; +} + +int32_t +SBUnixSignals::GetNumSignals () const +{ + if (auto process_sp = GetSP()) + { + // only valid while we hold process_sp + UnixSignals *unix_signals_ptr = &process_sp->GetUnixSignals(); + int32_t num_signals = 0; + for (int32_t signo = unix_signals_ptr->GetFirstSignalNumber(); + signo != LLDB_INVALID_SIGNAL_NUMBER; + signo = unix_signals_ptr->GetNextSignalNumber(signo)) + { + num_signals++; + } + return num_signals; + } + return LLDB_INVALID_SIGNAL_NUMBER; +} + +int32_t +SBUnixSignals::GetSignalAtIndex (int32_t index) const +{ + if (auto process_sp = GetSP()) + { + // only valid while we hold process_sp + UnixSignals *unix_signals_ptr = &process_sp->GetUnixSignals(); + int32_t idx = 0; + for (int32_t signo = unix_signals_ptr->GetFirstSignalNumber(); + signo != LLDB_INVALID_SIGNAL_NUMBER; + signo = unix_signals_ptr->GetNextSignalNumber(signo)) + { + if (index == idx) return signo; + idx++; + } + } + return LLDB_INVALID_SIGNAL_NUMBER; +} diff --git a/source/API/SBValue.cpp b/source/API/SBValue.cpp index 4bd018352ff2..3a9621b1e3bc 100644 --- a/source/API/SBValue.cpp +++ b/source/API/SBValue.cpp @@ -58,7 +58,7 @@ public: ValueImpl () { } - + ValueImpl (lldb::ValueObjectSP in_valobj_sp, lldb::DynamicValueType use_dynamic, bool use_synthetic, @@ -71,7 +71,7 @@ public: if (!m_name.IsEmpty() && m_valobj_sp) m_valobj_sp->SetName(m_name); } - + ValueImpl (const ValueImpl& rhs) : m_valobj_sp(rhs.m_valobj_sp), m_use_dynamic(rhs.m_use_dynamic), @@ -79,7 +79,7 @@ public: m_name (rhs.m_name) { } - + ValueImpl & operator = (const ValueImpl &rhs) { @@ -92,7 +92,7 @@ public: } return *this; } - + bool IsValid () { @@ -115,13 +115,13 @@ public: return false; } } - + lldb::ValueObjectSP GetRootSP () { return m_valobj_sp; } - + lldb::ValueObjectSP GetSP (Process::StopLocker &stop_locker, Mutex::Locker &api_locker, Error &error) { @@ -131,26 +131,27 @@ public: error.SetErrorString("invalid value object"); return m_valobj_sp; } - + lldb::ValueObjectSP value_sp = m_valobj_sp; - + Target *target = value_sp->GetTargetSP().get(); if (target) api_locker.Lock(target->GetAPIMutex()); else return ValueObjectSP(); - + ProcessSP process_sp(value_sp->GetProcessSP()); if (process_sp && !stop_locker.TryLock (&process_sp->GetRunLock())) { // We don't allow people to play around with ValueObject if the process is running. // If you want to look at values, pause the process, then look. if (log) - log->Printf ("SBValue(%p)::GetSP() => error: process is running", value_sp.get()); + log->Printf ("SBValue(%p)::GetSP() => error: process is running", + static_cast(value_sp.get())); error.SetErrorString ("process must be stopped."); return ValueObjectSP(); } - + if (value_sp->GetDynamicValue(m_use_dynamic)) value_sp = value_sp->GetDynamicValue(m_use_dynamic); if (value_sp->GetSyntheticValue(m_use_synthetic)) @@ -159,34 +160,34 @@ public: error.SetErrorString("invalid value object"); if (!m_name.IsEmpty()) value_sp->SetName(m_name); - + return value_sp; } - + void SetUseDynamic (lldb::DynamicValueType use_dynamic) { m_use_dynamic = use_dynamic; } - + void SetUseSynthetic (bool use_synthetic) { m_use_synthetic = use_synthetic; } - + lldb::DynamicValueType GetUseDynamic () { return m_use_dynamic; } - + bool GetUseSynthetic () { return m_use_synthetic; } - + // All the derived values that we would make from the m_valobj_sp will share // the ExecutionContext with m_valobj_sp, so we don't need to do the calculations // in GetSP to return the Target, Process, Thread or Frame. It is convenient to @@ -199,7 +200,7 @@ public: else return TargetSP(); } - + ProcessSP GetProcessSP () { @@ -208,7 +209,7 @@ public: else return ProcessSP(); } - + ThreadSP GetThreadSP () { @@ -217,7 +218,7 @@ public: else return ThreadSP(); } - + StackFrameSP GetFrameSP () { @@ -226,7 +227,7 @@ public: else return StackFrameSP(); } - + private: lldb::ValueObjectSP m_valobj_sp; lldb::DynamicValueType m_use_dynamic; @@ -337,16 +338,18 @@ SBValue::GetName() lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) name = value_sp->GetName().GetCString(); - + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (name) - log->Printf ("SBValue(%p)::GetName () => \"%s\"", value_sp.get(), name); + log->Printf ("SBValue(%p)::GetName () => \"%s\"", + static_cast(value_sp.get()), name); else - log->Printf ("SBValue(%p)::GetName () => NULL", value_sp.get()); + log->Printf ("SBValue(%p)::GetName () => NULL", + static_cast(value_sp.get())); } - + return name; } @@ -361,13 +364,40 @@ SBValue::GetTypeName () { name = value_sp->GetQualifiedTypeName().GetCString(); } + + if (log) + { + if (name) + log->Printf ("SBValue(%p)::GetTypeName () => \"%s\"", + static_cast(value_sp.get()), name); + else + log->Printf ("SBValue(%p)::GetTypeName () => NULL", + static_cast(value_sp.get())); + } + + return name; +} + +const char * +SBValue::GetDisplayTypeName () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + const char *name = NULL; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + name = value_sp->GetDisplayTypeName().GetCString(); + } if (log) { if (name) - log->Printf ("SBValue(%p)::GetTypeName () => \"%s\"", value_sp.get(), name); + log->Printf ("SBValue(%p)::GetTypeName () => \"%s\"", + static_cast(value_sp.get()), name); else - log->Printf ("SBValue(%p)::GetTypeName () => NULL", value_sp.get()); + log->Printf ("SBValue(%p)::GetTypeName () => NULL", + static_cast(value_sp.get())); } return name; @@ -378,17 +408,19 @@ SBValue::GetByteSize () { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); size_t result = 0; - + ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) { result = value_sp->GetByteSize(); } - + if (log) - log->Printf ("SBValue(%p)::GetByteSize () => %" PRIu64, value_sp.get(), (uint64_t)result); - + log->Printf ("SBValue(%p)::GetByteSize () => %" PRIu64, + static_cast(value_sp.get()), + static_cast(result)); + return result; } @@ -396,18 +428,19 @@ bool SBValue::IsInScope () { bool result = false; - + ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) { result = value_sp->IsInScope (); } - + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBValue(%p)::IsInScope () => %i", value_sp.get(), result); - + log->Printf ("SBValue(%p)::IsInScope () => %i", + static_cast(value_sp.get()), result); + return result; } @@ -415,7 +448,7 @@ const char * SBValue::GetValue () { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + const char *cstr = NULL; ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); @@ -426,11 +459,13 @@ SBValue::GetValue () if (log) { if (cstr) - log->Printf ("SBValue(%p)::GetValue() => \"%s\"", value_sp.get(), cstr); + log->Printf ("SBValue(%p)::GetValue() => \"%s\"", + static_cast(value_sp.get()), cstr); else - log->Printf ("SBValue(%p)::GetValue() => NULL", value_sp.get()); + log->Printf ("SBValue(%p)::GetValue() => NULL", + static_cast(value_sp.get())); } - + return cstr; } @@ -442,20 +477,44 @@ SBValue::GetValueType () lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) result = value_sp->GetValueType(); - + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { switch (result) { - case eValueTypeInvalid: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeInvalid", value_sp.get()); break; - case eValueTypeVariableGlobal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal", value_sp.get()); break; - case eValueTypeVariableStatic: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableStatic", value_sp.get()); break; - case eValueTypeVariableArgument:log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableArgument", value_sp.get()); break; - case eValueTypeVariableLocal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableLocal", value_sp.get()); break; - case eValueTypeRegister: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister", value_sp.get()); break; - case eValueTypeRegisterSet: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", value_sp.get()); break; - case eValueTypeConstResult: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult", value_sp.get()); break; + case eValueTypeInvalid: + log->Printf ("SBValue(%p)::GetValueType () => eValueTypeInvalid", + static_cast(value_sp.get())); + break; + case eValueTypeVariableGlobal: + log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal", + static_cast(value_sp.get())); + break; + case eValueTypeVariableStatic: + log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableStatic", + static_cast(value_sp.get())); + break; + case eValueTypeVariableArgument: + log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableArgument", + static_cast(value_sp.get())); + break; + case eValueTypeVariableLocal: + log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableLocal", + static_cast(value_sp.get())); + break; + case eValueTypeRegister: + log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister", + static_cast(value_sp.get())); + break; + case eValueTypeRegisterSet: + log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", + static_cast(value_sp.get())); + break; + case eValueTypeConstResult: + log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult", + static_cast(value_sp.get())); + break; } } return result; @@ -475,9 +534,11 @@ SBValue::GetObjectDescription () if (log) { if (cstr) - log->Printf ("SBValue(%p)::GetObjectDescription() => \"%s\"", value_sp.get(), cstr); + log->Printf ("SBValue(%p)::GetObjectDescription() => \"%s\"", + static_cast(value_sp.get()), cstr); else - log->Printf ("SBValue(%p)::GetObjectDescription() => NULL", value_sp.get()); + log->Printf ("SBValue(%p)::GetObjectDescription() => NULL", + static_cast(value_sp.get())); } return cstr; } @@ -498,9 +559,12 @@ SBValue::GetType() if (log) { if (type_sp) - log->Printf ("SBValue(%p)::GetType => SBType(%p)", value_sp.get(), type_sp.get()); + log->Printf ("SBValue(%p)::GetType => SBType(%p)", + static_cast(value_sp.get()), + static_cast(type_sp.get())); else - log->Printf ("SBValue(%p)::GetType => NULL", value_sp.get()); + log->Printf ("SBValue(%p)::GetType => NULL", + static_cast(value_sp.get())); } return sb_type; } @@ -517,8 +581,9 @@ SBValue::GetValueDidChange () result = value_sp->GetValueDidChange (); } if (log) - log->Printf ("SBValue(%p)::GetValueDidChange() => %i", value_sp.get(), result); - + log->Printf ("SBValue(%p)::GetValueDidChange() => %i", + static_cast(value_sp.get()), result); + return result; } @@ -537,9 +602,11 @@ SBValue::GetSummary () if (log) { if (cstr) - log->Printf ("SBValue(%p)::GetSummary() => \"%s\"", value_sp.get(), cstr); + log->Printf ("SBValue(%p)::GetSummary() => \"%s\"", + static_cast(value_sp.get()), cstr); else - log->Printf ("SBValue(%p)::GetSummary() => NULL", value_sp.get()); + log->Printf ("SBValue(%p)::GetSummary() => NULL", + static_cast(value_sp.get())); } return cstr; } @@ -559,9 +626,11 @@ SBValue::GetLocation () if (log) { if (cstr) - log->Printf ("SBValue(%p)::GetLocation() => \"%s\"", value_sp.get(), cstr); + log->Printf ("SBValue(%p)::GetLocation() => \"%s\"", + static_cast(value_sp.get()), cstr); else - log->Printf ("SBValue(%p)::GetLocation() => NULL", value_sp.get()); + log->Printf ("SBValue(%p)::GetLocation() => NULL", + static_cast(value_sp.get())); } return cstr; } @@ -587,10 +656,11 @@ SBValue::SetValueFromCString (const char *value_str, lldb::SBError& error) } else error.SetErrorStringWithFormat ("Could not get value: %s", locker.GetError().AsCString()); - + if (log) - log->Printf ("SBValue(%p)::SetValueFromCString(\"%s\") => %i", value_sp.get(), value_str, success); - + log->Printf ("SBValue(%p)::SetValueFromCString(\"%s\") => %i", + static_cast(value_sp.get()), value_str, success); + return success; } @@ -698,11 +768,11 @@ SBValue::CreateChildAtOffset (const char *name, uint32_t offset, SBType type) { if (new_value_sp) log->Printf ("SBValue(%p)::CreateChildAtOffset => \"%s\"", - value_sp.get(), + static_cast(value_sp.get()), new_value_sp->GetName().AsCString()); else log->Printf ("SBValue(%p)::CreateChildAtOffset => NULL", - value_sp.get()); + static_cast(value_sp.get())); } return sb_value; } @@ -757,15 +827,11 @@ SBValue::CreateValueFromExpression (const char *name, const char *expression, SB { if (new_value_sp) log->Printf ("SBValue(%p)::CreateValueFromExpression(name=\"%s\", expression=\"%s\") => SBValue (%p)", - value_sp.get(), - name, - expression, - new_value_sp.get()); + static_cast(value_sp.get()), name, expression, + static_cast(new_value_sp.get())); else log->Printf ("SBValue(%p)::CreateValueFromExpression(name=\"%s\", expression=\"%s\") => NULL", - value_sp.get(), - name, - expression); + static_cast(value_sp.get()), name, expression); } return sb_value; } @@ -784,7 +850,7 @@ SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType s if (pointer_ast_type) { lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t))); - + ExecutionContext exe_ctx (value_sp->GetExecutionContextRef()); ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), pointer_ast_type, @@ -792,7 +858,7 @@ SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType s buffer, exe_ctx.GetByteOrder(), exe_ctx.GetAddressByteSize())); - + if (ptr_result_valobj_sp) { ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress); @@ -808,9 +874,12 @@ SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType s if (log) { if (new_value_sp) - log->Printf ("SBValue(%p)::CreateValueFromAddress => \"%s\"", value_sp.get(), new_value_sp->GetName().AsCString()); + log->Printf ("SBValue(%p)::CreateValueFromAddress => \"%s\"", + static_cast(value_sp.get()), + new_value_sp->GetName().AsCString()); else - log->Printf ("SBValue(%p)::CreateValueFromAddress => NULL", value_sp.get()); + log->Printf ("SBValue(%p)::CreateValueFromAddress => NULL", + static_cast(value_sp.get())); } return sb_value; } @@ -825,7 +894,7 @@ SBValue::CreateValueFromData (const char* name, SBData data, SBType type) if (value_sp) { ExecutionContext exe_ctx (value_sp->GetExecutionContextRef()); - + new_value_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), type.m_opaque_sp->GetClangASTType(false), ConstString(name), @@ -838,9 +907,12 @@ SBValue::CreateValueFromData (const char* name, SBData data, SBType type) if (log) { if (new_value_sp) - log->Printf ("SBValue(%p)::CreateValueFromData => \"%s\"", value_sp.get(), new_value_sp->GetName().AsCString()); + log->Printf ("SBValue(%p)::CreateValueFromData => \"%s\"", + static_cast(value_sp.get()), + new_value_sp->GetName().AsCString()); else - log->Printf ("SBValue(%p)::CreateValueFromData => NULL", value_sp.get()); + log->Printf ("SBValue(%p)::CreateValueFromData => NULL", + static_cast(value_sp.get())); } return sb_value; } @@ -865,7 +937,7 @@ SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic, bool { lldb::ValueObjectSP child_sp; Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) @@ -884,12 +956,14 @@ SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic, bool } } } - + SBValue sb_value; sb_value.SetSP (child_sp, use_dynamic, GetPreferSyntheticValue()); if (log) - log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", value_sp.get(), idx, value_sp.get()); - + log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", + static_cast(value_sp.get()), idx, + static_cast(value_sp.get())); + return sb_value; } @@ -907,9 +981,11 @@ SBValue::GetIndexOfChildWithName (const char *name) if (log) { if (idx == UINT32_MAX) - log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", value_sp.get(), name); + log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", + static_cast(value_sp.get()), name); else - log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", value_sp.get(), name, idx); + log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", + static_cast(value_sp.get()), name, idx); } return idx; } @@ -921,7 +997,7 @@ SBValue::GetChildMemberWithName (const char *name) TargetSP target_sp; if (m_opaque_sp) target_sp = m_opaque_sp->GetTargetSP(); - + if (target_sp) use_dynamic_value = target_sp->GetPreferDynamicValue(); return GetChildMemberWithName (name, use_dynamic_value); @@ -932,22 +1008,24 @@ SBValue::GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dy { lldb::ValueObjectSP child_sp; const ConstString str_name (name); - + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - + ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) { child_sp = value_sp->GetChildMemberWithName (str_name, true); } - + SBValue sb_value; sb_value.SetSP(child_sp, use_dynamic_value, GetPreferSyntheticValue()); - + if (log) - log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", value_sp.get(), name, value_sp.get()); - + log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", + static_cast(value_sp.get()), name, + static_cast(value_sp.get())); + return sb_value; } @@ -1049,13 +1127,15 @@ SBValue::GetValueForExpressionPath(const char* expr_path) // using default values for all the fancy options, just do it if you can child_sp = value_sp->GetValueForExpressionPath(expr_path); } - + SBValue sb_value; sb_value.SetSP(child_sp,GetPreferDynamicValue(),GetPreferSyntheticValue()); - + if (log) - log->Printf ("SBValue(%p)::GetValueForExpressionPath (expr_path=\"%s\") => SBValue(%p)", value_sp.get(), expr_path, value_sp.get()); - + log->Printf ("SBValue(%p)::GetValueForExpressionPath (expr_path=\"%s\") => SBValue(%p)", + static_cast(value_sp.get()), expr_path, + static_cast(value_sp.get())); + return sb_value; } @@ -1134,9 +1214,10 @@ SBValue::MightHaveChildren () lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) has_children = value_sp->MightHaveChildren(); - + if (log) - log->Printf ("SBValue(%p)::MightHaveChildren() => %i", value_sp.get(), has_children); + log->Printf ("SBValue(%p)::MightHaveChildren() => %i", + static_cast(value_sp.get()), has_children); return has_children; } @@ -1144,16 +1225,17 @@ uint32_t SBValue::GetNumChildren () { uint32_t num_children = 0; - + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) num_children = value_sp->GetNumChildren(); - + if (log) - log->Printf ("SBValue(%p)::GetNumChildren () => %u", value_sp.get(), num_children); - + log->Printf ("SBValue(%p)::GetNumChildren () => %u", + static_cast(value_sp.get()), num_children); + return num_children; } @@ -1171,8 +1253,10 @@ SBValue::Dereference () } Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)", value_sp.get(), value_sp.get()); - + log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)", + static_cast(value_sp.get()), + static_cast(value_sp.get())); + return sb_value; } @@ -1180,17 +1264,17 @@ bool SBValue::TypeIsPointerType () { bool is_ptr_type = false; - + ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) is_ptr_type = value_sp->IsPointerType(); - + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBValue(%p)::TypeIsPointerType () => %i", value_sp.get(), is_ptr_type); - - + log->Printf ("SBValue(%p)::TypeIsPointerType () => %i", + static_cast(value_sp.get()), is_ptr_type); + return is_ptr_type; } @@ -1218,9 +1302,12 @@ SBValue::GetTarget() if (log) { if (target_sp.get() == NULL) - log->Printf ("SBValue(%p)::GetTarget () => NULL", m_opaque_sp.get()); + log->Printf ("SBValue(%p)::GetTarget () => NULL", + static_cast(m_opaque_sp.get())); else - log->Printf ("SBValue(%p)::GetTarget () => %p", m_opaque_sp.get(), target_sp.get()); + log->Printf ("SBValue(%p)::GetTarget () => %p", + static_cast(m_opaque_sp.get()), + static_cast(target_sp.get())); } return sb_target; } @@ -1239,9 +1326,12 @@ SBValue::GetProcess() if (log) { if (process_sp.get() == NULL) - log->Printf ("SBValue(%p)::GetProcess () => NULL", m_opaque_sp.get()); + log->Printf ("SBValue(%p)::GetProcess () => NULL", + static_cast(m_opaque_sp.get())); else - log->Printf ("SBValue(%p)::GetProcess () => %p", m_opaque_sp.get(), process_sp.get()); + log->Printf ("SBValue(%p)::GetProcess () => %p", + static_cast(m_opaque_sp.get()), + static_cast(process_sp.get())); } return sb_process; } @@ -1260,9 +1350,12 @@ SBValue::GetThread() if (log) { if (thread_sp.get() == NULL) - log->Printf ("SBValue(%p)::GetThread () => NULL", m_opaque_sp.get()); + log->Printf ("SBValue(%p)::GetThread () => NULL", + static_cast(m_opaque_sp.get())); else - log->Printf ("SBValue(%p)::GetThread () => %p", m_opaque_sp.get(), thread_sp.get()); + log->Printf ("SBValue(%p)::GetThread () => %p", + static_cast(m_opaque_sp.get()), + static_cast(thread_sp.get())); } return sb_thread; } @@ -1281,9 +1374,12 @@ SBValue::GetFrame() if (log) { if (frame_sp.get() == NULL) - log->Printf ("SBValue(%p)::GetFrame () => NULL", m_opaque_sp.get()); + log->Printf ("SBValue(%p)::GetFrame () => NULL", + static_cast(m_opaque_sp.get())); else - log->Printf ("SBValue(%p)::GetFrame () => %p", m_opaque_sp.get(), frame_sp.get()); + log->Printf ("SBValue(%p)::GetFrame () => %p", + static_cast(m_opaque_sp.get()), + static_cast(frame_sp.get())); } return sb_frame; } @@ -1450,8 +1546,10 @@ SBValue::AddressOf() } Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBValue(%p)::AddressOf () => SBValue(%p)", value_sp.get(), value_sp.get()); - + log->Printf ("SBValue(%p)::AddressOf () => SBValue(%p)", + static_cast(value_sp.get()), + static_cast(value_sp.get())); + return sb_value; } @@ -1487,8 +1585,9 @@ SBValue::GetLoadAddress() } Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBValue(%p)::GetLoadAddress () => (%" PRIu64 ")", value_sp.get(), value); - + log->Printf ("SBValue(%p)::GetLoadAddress () => (%" PRIu64 ")", + static_cast(value_sp.get()), value); + return value; } @@ -1524,8 +1623,11 @@ SBValue::GetAddress() } Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBValue(%p)::GetAddress () => (%s,%" PRIu64 ")", value_sp.get(), - (addr.GetSection() ? addr.GetSection()->GetName().GetCString() : "NULL"), + log->Printf ("SBValue(%p)::GetAddress () => (%s,%" PRIu64 ")", + static_cast(value_sp.get()), + (addr.GetSection() + ? addr.GetSection()->GetName().GetCString() + : "NULL"), addr.GetOffset()); return SBAddress(new Address(addr)); } @@ -1551,11 +1653,9 @@ SBValue::GetPointeeData (uint32_t item_idx, } if (log) log->Printf ("SBValue(%p)::GetPointeeData (%d, %d) => SBData(%p)", - value_sp.get(), - item_idx, - item_count, - sb_data.get()); - + static_cast(value_sp.get()), item_idx, item_count, + static_cast(sb_data.get())); + return sb_data; } @@ -1569,15 +1669,16 @@ SBValue::GetData () if (value_sp) { DataExtractorSP data_sp(new DataExtractor()); - value_sp->GetData(*data_sp); - if (data_sp->GetByteSize() > 0) + Error error; + value_sp->GetData(*data_sp, error); + if (error.Success()) *sb_data = data_sp; } if (log) log->Printf ("SBValue(%p)::GetData () => SBData(%p)", - value_sp.get(), - sb_data.get()); - + static_cast(value_sp.get()), + static_cast(sb_data.get())); + return sb_data; } @@ -1588,25 +1689,26 @@ SBValue::SetData (lldb::SBData &data, SBError &error) ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); bool ret = true; - + if (value_sp) { DataExtractor *data_extractor = data.get(); - + if (!data_extractor) { if (log) - log->Printf ("SBValue(%p)::SetData() => error: no data to set", value_sp.get()); - + log->Printf ("SBValue(%p)::SetData() => error: no data to set", + static_cast(value_sp.get())); + error.SetErrorString("No data to set"); ret = false; } else { Error set_error; - + value_sp->SetData(*data_extractor, set_error); - + if (!set_error.Success()) { error.SetErrorStringWithFormat("Couldn't set data: %s", set_error.AsCString()); @@ -1619,12 +1721,11 @@ SBValue::SetData (lldb::SBData &data, SBError &error) error.SetErrorStringWithFormat ("Couldn't set data: could not get SBValue: %s", locker.GetError().AsCString()); ret = false; } - + if (log) log->Printf ("SBValue(%p)::SetData (%p) => %s", - value_sp.get(), - data.get(), - ret ? "true" : "false"); + static_cast(value_sp.get()), + static_cast(data.get()), ret ? "true" : "false"); return ret; } @@ -1647,7 +1748,7 @@ lldb::SBWatchpoint SBValue::Watch (bool resolve_location, bool read, bool write, SBError &error) { SBWatchpoint sb_watchpoint; - + // If the SBValue is not valid, there's no point in even trying to watch it. ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); @@ -1657,29 +1758,29 @@ SBValue::Watch (bool resolve_location, bool read, bool write, SBError &error) // Read and Write cannot both be false. if (!read && !write) return sb_watchpoint; - + // If the value is not in scope, don't try and watch and invalid value if (!IsInScope()) return sb_watchpoint; - + addr_t addr = GetLoadAddress(); if (addr == LLDB_INVALID_ADDRESS) return sb_watchpoint; size_t byte_size = GetByteSize(); if (byte_size == 0) return sb_watchpoint; - + uint32_t watch_type = 0; if (read) watch_type |= LLDB_WATCH_TYPE_READ; if (write) watch_type |= LLDB_WATCH_TYPE_WRITE; - + Error rc; ClangASTType type (value_sp->GetClangType()); WatchpointSP watchpoint_sp = target_sp->CreateWatchpoint(addr, byte_size, &type, watch_type, rc); error.SetError(rc); - + if (watchpoint_sp) { sb_watchpoint.SetSP (watchpoint_sp); @@ -1700,18 +1801,21 @@ SBValue::Watch (bool resolve_location, bool read, bool write, SBError &error) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBValue(%p)::Watch() => error getting SBValue: %s", value_sp.get(), locker.GetError().AsCString()); - + log->Printf ("SBValue(%p)::Watch() => error getting SBValue: %s", + static_cast(value_sp.get()), + locker.GetError().AsCString()); + error.SetErrorStringWithFormat("could not get SBValue: %s", locker.GetError().AsCString()); } else { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBValue(%p)::Watch() => error getting SBValue: no target", value_sp.get()); + log->Printf ("SBValue(%p)::Watch() => error getting SBValue: no target", + static_cast(value_sp.get())); error.SetErrorString("could not set watchpoint, a target is required"); } - + return sb_watchpoint; } diff --git a/source/API/SBValueList.cpp b/source/API/SBValueList.cpp index 46866eb37424..5069ed3f5624 100644 --- a/source/API/SBValueList.cpp +++ b/source/API/SBValueList.cpp @@ -99,8 +99,8 @@ SBValueList::SBValueList (const SBValueList &rhs) : if (log) { log->Printf ("SBValueList::SBValueList (rhs.ap=%p) => this.ap = %p", - (rhs.IsValid() ? rhs.m_opaque_ap.get() : NULL), - m_opaque_ap.get()); + static_cast(rhs.IsValid() ? rhs.m_opaque_ap.get() : NULL), + static_cast(m_opaque_ap.get())); } } @@ -114,9 +114,9 @@ SBValueList::SBValueList (const ValueListImpl *lldb_object_ptr) : if (log) { - log->Printf ("SBValueList::SBValueList (lldb_object_ptr=%p) => this.ap = %p", - lldb_object_ptr, - m_opaque_ap.get()); + log->Printf ("SBValueList::SBValueList (lldb_object_ptr=%p) => this.ap = %p", + static_cast(lldb_object_ptr), + static_cast(m_opaque_ap.get())); } } @@ -218,7 +218,8 @@ SBValueList::GetValueAtIndex (uint32_t idx) const SBStream sstr; sb_value.GetDescription (sstr); log->Printf ("SBValueList::GetValueAtIndex (this.ap=%p, idx=%d) => SBValue (this.sp = %p, '%s')", - m_opaque_ap.get(), idx, sb_value.GetSP().get(), sstr.GetData()); + static_cast(m_opaque_ap.get()), idx, + static_cast(sb_value.GetSP().get()), sstr.GetData()); } return sb_value; @@ -237,7 +238,8 @@ SBValueList::GetSize () const size = m_opaque_ap->GetSize(); if (log) - log->Printf ("SBValueList::GetSize (this.ap=%p) => %d", m_opaque_ap.get(), size); + log->Printf ("SBValueList::GetSize (this.ap=%p) => %d", + static_cast(m_opaque_ap.get()), size); return size; } diff --git a/source/API/SBWatchpoint.cpp b/source/API/SBWatchpoint.cpp index 194695c31d5b..1a1a970aaa87 100644 --- a/source/API/SBWatchpoint.cpp +++ b/source/API/SBWatchpoint.cpp @@ -42,7 +42,9 @@ SBWatchpoint::SBWatchpoint (const lldb::WatchpointSP &wp_sp) : SBStream sstr; GetDescription (sstr, lldb::eDescriptionLevelBrief); log->Printf ("SBWatchpoint::SBWatchpoint (const lldb::WatchpointSP &wp_sp" - "=%p) => this.sp = %p (%s)", wp_sp.get(), m_opaque_sp.get(), sstr.GetData()); + "=%p) => this.sp = %p (%s)", + static_cast(wp_sp.get()), + static_cast(m_opaque_sp.get()), sstr.GetData()); } } @@ -77,9 +79,11 @@ SBWatchpoint::GetID () if (log) { if (watch_id == LLDB_INVALID_WATCH_ID) - log->Printf ("SBWatchpoint(%p)::GetID () => LLDB_INVALID_WATCH_ID", watchpoint_sp.get()); + log->Printf ("SBWatchpoint(%p)::GetID () => LLDB_INVALID_WATCH_ID", + static_cast(watchpoint_sp.get())); else - log->Printf ("SBWatchpoint(%p)::GetID () => %u", watchpoint_sp.get(), watch_id); + log->Printf ("SBWatchpoint(%p)::GetID () => %u", + static_cast(watchpoint_sp.get()), watch_id); } return watch_id; @@ -185,7 +189,8 @@ SBWatchpoint::GetHitCount () Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) - log->Printf ("SBWatchpoint(%p)::GetHitCount () => %u", watchpoint_sp.get(), count); + log->Printf ("SBWatchpoint(%p)::GetHitCount () => %u", + static_cast(watchpoint_sp.get()), count); return count; } diff --git a/source/Breakpoint/Breakpoint.cpp b/source/Breakpoint/Breakpoint.cpp index 5ce064fc41a0..7d08170e4aed 100644 --- a/source/Breakpoint/Breakpoint.cpp +++ b/source/Breakpoint/Breakpoint.cpp @@ -541,7 +541,7 @@ Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_l if (!m_kind_description.empty()) { - if (eDescriptionLevelBrief) + if (level == eDescriptionLevelBrief) { s->PutCString (GetBreakpointKind()); return; diff --git a/source/Breakpoint/BreakpointID.cpp b/source/Breakpoint/BreakpointID.cpp index 9a59e29d007d..9963ed68303a 100644 --- a/source/Breakpoint/BreakpointID.cpp +++ b/source/Breakpoint/BreakpointID.cpp @@ -71,7 +71,7 @@ void BreakpointID::GetDescription (Stream *s, lldb::DescriptionLevel level) { if (level == eDescriptionLevelVerbose) - s->Printf("%p BreakpointID:", this); + s->Printf("%p BreakpointID:", static_cast(this)); if (m_break_id == LLDB_INVALID_BREAK_ID) s->PutCString (""); diff --git a/source/Breakpoint/BreakpointList.cpp b/source/Breakpoint/BreakpointList.cpp index 147ad36b0407..650737761547 100644 --- a/source/Breakpoint/BreakpointList.cpp +++ b/source/Breakpoint/BreakpointList.cpp @@ -167,7 +167,7 @@ void BreakpointList::Dump (Stream *s) const { Mutex::Locker locker(m_mutex); - s->Printf("%p: ", this); + s->Printf("%p: ", static_cast(this)); s->Indent(); s->Printf("BreakpointList with %u Breakpoints:\n", (uint32_t)m_breakpoints.size()); s->IndentMore(); diff --git a/source/Breakpoint/BreakpointLocation.cpp b/source/Breakpoint/BreakpointLocation.cpp index 2c75a11e9788..e1ac043ae905 100644 --- a/source/Breakpoint/BreakpointLocation.cpp +++ b/source/Breakpoint/BreakpointLocation.cpp @@ -289,7 +289,8 @@ BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error) if (!m_user_expression_sp->Parse(errors, exe_ctx, eExecutionPolicyOnlyWhenNeeded, - true)) + true, + false)) { error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s", errors.GetData()); @@ -316,7 +317,7 @@ BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error) ClangExpressionVariableSP result_variable_sp; - ExecutionResults result_code = + ExpressionResults result_code = m_user_expression_sp->Execute(execution_errors, exe_ctx, options, @@ -325,11 +326,10 @@ BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error) bool ret; - if (result_code == eExecutionCompleted) + if (result_code == eExpressionCompleted) { if (!result_variable_sp) { - ret = false; error.SetErrorString("Expression did not return a result"); return false; } @@ -522,8 +522,15 @@ BreakpointLocation::ClearBreakpointSite () { if (m_bp_site_sp.get()) { - m_owner.GetTarget().GetProcessSP()->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(), + ProcessSP process_sp(m_owner.GetTarget().GetProcessSP()); + // If the process exists, get it to remove the owner, it will remove the physical implementation + // of the breakpoint as well if there are no more owners. Otherwise just remove this owner. + if (process_sp) + process_sp->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(), GetID(), m_bp_site_sp); + else + m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID()); + m_bp_site_sp.reset(); return true; } @@ -627,7 +634,7 @@ BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level) if (exe_scope == NULL) exe_scope = target; - if (eDescriptionLevelInitial) + if (level == eDescriptionLevelInitial) m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); else m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress); diff --git a/source/Breakpoint/BreakpointLocationList.cpp b/source/Breakpoint/BreakpointLocationList.cpp index 917c776e75d2..ae7f863ad090 100644 --- a/source/Breakpoint/BreakpointLocationList.cpp +++ b/source/Breakpoint/BreakpointLocationList.cpp @@ -152,7 +152,7 @@ BreakpointLocationList::FindByAddress (const Address &addr) const void BreakpointLocationList::Dump (Stream *s) const { - s->Printf("%p: ", this); + s->Printf("%p: ", static_cast(this)); //s->Indent(); Mutex::Locker locker (m_mutex); s->Printf("BreakpointLocationList with %" PRIu64 " BreakpointLocations:\n", (uint64_t)m_locations.size()); diff --git a/source/Breakpoint/BreakpointOptions.cpp b/source/Breakpoint/BreakpointOptions.cpp index 3a4a117695fc..ea8556d0930b 100644 --- a/source/Breakpoint/BreakpointOptions.cpp +++ b/source/Breakpoint/BreakpointOptions.cpp @@ -154,7 +154,7 @@ BreakpointOptions::InvokeCallback (StoppointCallbackContext *context, } bool -BreakpointOptions::HasCallback () +BreakpointOptions::HasCallback () const { return m_callback != BreakpointOptions::NullCallback; } diff --git a/source/Breakpoint/BreakpointResolverName.cpp b/source/Breakpoint/BreakpointResolverName.cpp index cf5d89cb7a8b..3ac3ed06fc70 100644 --- a/source/Breakpoint/BreakpointResolverName.cpp +++ b/source/Breakpoint/BreakpointResolverName.cpp @@ -234,7 +234,7 @@ BreakpointResolverName::SearchCallback if (context.module_sp) { context.module_sp->FindFunctions (m_regex, - !filter_by_cu, // include symbols only if we aren't filterning by CU + !filter_by_cu, // include symbols only if we aren't filtering by CU include_inlines, append, func_list); @@ -264,7 +264,7 @@ BreakpointResolverName::SearchCallback } } - // Remove any duplicates between the funcion list and the symbol list + // Remove any duplicates between the function list and the symbol list SymbolContext sc; if (func_list.GetSize()) { diff --git a/source/Breakpoint/BreakpointSite.cpp b/source/Breakpoint/BreakpointSite.cpp index fa5d8c1f9f81..3cf6d37af379 100644 --- a/source/Breakpoint/BreakpointSite.cpp +++ b/source/Breakpoint/BreakpointSite.cpp @@ -32,7 +32,8 @@ BreakpointSite::BreakpointSite m_saved_opcode(), m_trap_opcode(), m_enabled(false), // Need to create it disabled, so the first enable turns it on. - m_owners() + m_owners(), + m_owners_mutex(Mutex::eMutexTypeRecursive) { m_owners.Add(owner); } @@ -60,6 +61,7 @@ BreakpointSite::GetNextID() bool BreakpointSite::ShouldStop (StoppointCallbackContext *context) { + Mutex::Locker locker(m_owners_mutex); IncrementHitCount(); return m_owners.ShouldStop (context); } @@ -67,6 +69,7 @@ BreakpointSite::ShouldStop (StoppointCallbackContext *context) bool BreakpointSite::IsBreakpointAtThisSite (lldb::break_id_t bp_id) { + Mutex::Locker locker(m_owners_mutex); const size_t owner_count = m_owners.GetSize(); for (size_t i = 0; i < owner_count; i++) { @@ -93,6 +96,7 @@ BreakpointSite::Dump(Stream *s) const void BreakpointSite::GetDescription (Stream *s, lldb::DescriptionLevel level) { + Mutex::Locker locker(m_owners_mutex); if (level != lldb::eDescriptionLevelBrief) s->Printf ("breakpoint site: %d at 0x%8.8" PRIx64, GetID(), GetLoadAddress()); m_owners.GetDescription (s, level); @@ -162,12 +166,14 @@ BreakpointSite::SetEnabled (bool enabled) void BreakpointSite::AddOwner (const BreakpointLocationSP &owner) { + Mutex::Locker locker(m_owners_mutex); m_owners.Add(owner); } size_t BreakpointSite::RemoveOwner (lldb::break_id_t break_id, lldb::break_id_t break_loc_id) { + Mutex::Locker locker(m_owners_mutex); m_owners.Remove(break_id, break_loc_id); return m_owners.GetSize(); } @@ -175,18 +181,21 @@ BreakpointSite::RemoveOwner (lldb::break_id_t break_id, lldb::break_id_t break_l size_t BreakpointSite::GetNumberOfOwners () { + Mutex::Locker locker(m_owners_mutex); return m_owners.GetSize(); } BreakpointLocationSP BreakpointSite::GetOwnerAtIndex (size_t index) { + Mutex::Locker locker(m_owners_mutex); return m_owners.GetByIndex (index); } bool BreakpointSite::ValidForThisThread (Thread *thread) { + Mutex::Locker locker(m_owners_mutex); return m_owners.ValidForThisThread(thread); } diff --git a/source/Breakpoint/BreakpointSiteList.cpp b/source/Breakpoint/BreakpointSiteList.cpp index 68c4af18ec5e..1eaadb62a384 100644 --- a/source/Breakpoint/BreakpointSiteList.cpp +++ b/source/Breakpoint/BreakpointSiteList.cpp @@ -186,7 +186,7 @@ BreakpointSiteList::BreakpointSiteContainsBreakpoint (lldb::break_id_t bp_site_i void BreakpointSiteList::Dump (Stream *s) const { - s->Printf("%p: ", this); + s->Printf("%p: ", static_cast(this)); //s->Indent(); s->Printf("BreakpointSiteList with %u BreakpointSites:\n", (uint32_t)m_bp_site_list.size()); s->IndentMore(); diff --git a/source/Breakpoint/WatchpointList.cpp b/source/Breakpoint/WatchpointList.cpp index 6d62dffd22cc..472bae06b441 100644 --- a/source/Breakpoint/WatchpointList.cpp +++ b/source/Breakpoint/WatchpointList.cpp @@ -55,7 +55,7 @@ void WatchpointList::DumpWithLevel (Stream *s, lldb::DescriptionLevel description_level) const { Mutex::Locker locker (m_mutex); - s->Printf("%p: ", this); + s->Printf("%p: ", static_cast(this)); //s->Indent(); s->Printf("WatchpointList with %" PRIu64 " Watchpoints:\n", (uint64_t)m_watchpoints.size()); diff --git a/source/Commands/CommandCompletions.cpp b/source/Commands/CommandCompletions.cpp index 970aa692bd27..f0ad4a896739 100644 --- a/source/Commands/CommandCompletions.cpp +++ b/source/Commands/CommandCompletions.cpp @@ -30,6 +30,8 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/CleanUp.h" +#include "llvm/ADT/SmallString.h" + using namespace lldb_private; CommandCompletions::CommonCompletionElement @@ -221,7 +223,7 @@ DiskFilesOrDirectories end_ptr = strrchr(partial_name_copy, '/'); // This will store the resolved form of the containing directory - char containing_part[PATH_MAX]; + llvm::SmallString<64> containing_part; if (end_ptr == NULL) { @@ -232,14 +234,11 @@ DiskFilesOrDirectories // Nothing here but the user name. We could just put a slash on the end, // but for completeness sake we'll resolve the user name and only put a slash // on the end if it exists. - char resolved_username[PATH_MAX]; - size_t resolved_username_len = FileSpec::ResolveUsername (partial_name_copy, resolved_username, - sizeof (resolved_username)); + llvm::SmallString<64> resolved_username(partial_name_copy); + FileSpec::ResolveUsername (resolved_username); // Not sure how this would happen, a username longer than PATH_MAX? Still... - if (resolved_username_len >= sizeof (resolved_username)) - return matches.GetSize(); - else if (resolved_username_len == 0) + if (resolved_username.size() == 0) { // The user name didn't resolve, let's look in the password database for matches. // The user name database contains duplicates, and is not in alphabetical order, so @@ -263,8 +262,7 @@ DiskFilesOrDirectories else { // The containing part is the CWD, and the whole string is the remainder. - containing_part[0] = '.'; - containing_part[1] = '\0'; + containing_part = "."; strcpy(remainder, partial_name_copy); end_ptr = partial_name_copy; } @@ -274,14 +272,11 @@ DiskFilesOrDirectories if (end_ptr == partial_name_copy) { // We're completing a file or directory in the root volume. - containing_part[0] = '/'; - containing_part[1] = '\0'; + containing_part = "/"; } else { - size_t len = end_ptr - partial_name_copy; - memcpy(containing_part, partial_name_copy, len); - containing_part[len] = '\0'; + containing_part.append(partial_name_copy, end_ptr); } // Push end_ptr past the final "/" and set remainder. end_ptr++; @@ -293,11 +288,9 @@ DiskFilesOrDirectories if (*partial_name_copy == '~') { - size_t resolved_username_len = FileSpec::ResolveUsername(containing_part, - containing_part, - sizeof (containing_part)); + FileSpec::ResolveUsername(containing_part); // User name doesn't exist, we're not getting any further... - if (resolved_username_len == 0 || resolved_username_len >= sizeof (containing_part)) + if (containing_part.empty()) return matches.GetSize(); } @@ -314,7 +307,7 @@ DiskFilesOrDirectories parameters.end_ptr = end_ptr; parameters.baselen = baselen; - FileSpec::EnumerateDirectory(containing_part, true, true, true, DiskFilesOrDirectoriesCallback, ¶meters); + FileSpec::EnumerateDirectory(containing_part.c_str(), true, true, true, DiskFilesOrDirectoriesCallback, ¶meters); return matches.GetSize(); } diff --git a/source/Commands/CommandObjectArgs.cpp b/source/Commands/CommandObjectArgs.cpp index 3b919d11a566..b0fe42bc2446 100644 --- a/source/Commands/CommandObjectArgs.cpp +++ b/source/Commands/CommandObjectArgs.cpp @@ -57,13 +57,7 @@ CommandObjectArgs::CommandOptions::SetOptionValue (uint32_t option_idx, const ch Error error; const int short_option = m_getopt_table[option_idx].val; - - switch (short_option) - { - default: - error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); - break; - } + error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); return error; } @@ -255,7 +249,7 @@ CommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result) for (arg_index = 0; arg_index < num_args; ++arg_index) { - result.GetOutputStream ().Printf ("%zu (%s): ", arg_index, args.GetArgumentAtIndex (arg_index)); + result.GetOutputStream ().Printf ("%" PRIu64 " (%s): ", (uint64_t)arg_index, args.GetArgumentAtIndex (arg_index)); value_list.GetValueAtIndex (arg_index)->Dump (&result.GetOutputStream ()); result.GetOutputStream ().Printf("\n"); } @@ -266,7 +260,7 @@ CommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result) OptionDefinition CommandObjectArgs::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp index c20da7f3ec5c..13bf1278c78c 100644 --- a/source/Commands/CommandObjectBreakpoint.cpp +++ b/source/Commands/CommandObjectBreakpoint.cpp @@ -154,9 +154,12 @@ public: case eLanguageTypeC89: case eLanguageTypeC: case eLanguageTypeC99: + case eLanguageTypeC11: m_language = eLanguageTypeC; break; case eLanguageTypeC_plus_plus: + case eLanguageTypeC_plus_plus_03: + case eLanguageTypeC_plus_plus_11: m_language = eLanguageTypeC_plus_plus; break; case eLanguageTypeObjC: @@ -623,41 +626,41 @@ private: OptionDefinition CommandObjectBreakpointSet::CommandOptions::g_option_table[] = { - { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, + { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the breakpoint only in this shared library. " "Can repeat this option multiple times to specify multiple shared libraries."}, - { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, + { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." }, - { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, + { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "The breakpoint is deleted the first time it causes a stop." }, - { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeExpression, + { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."}, - { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadIndex, + { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose indeX matches this argument."}, - { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadID, + { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."}, - { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadName, + { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."}, - { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, + { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Require the breakpoint to use hardware breakpoints."}, - { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, 0, eArgTypeQueueName, + { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."}, - { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, + { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file in which to set this breakpoint. " "Note, by default lldb only looks for files that are #included if they use the standard include file extensions. " "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy" " to \"always\"."}, - { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum, + { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, "Specifies the line number on which to set this breakpoint."}, // Comment out this option for the moment, as we don't actually use it, but will in the future. @@ -665,48 +668,48 @@ CommandObjectBreakpointSet::CommandOptions::g_option_table[] = // { 0, false, "column", 'C', OptionParser::eRequiredArgument, NULL, "", // "Set the breakpoint by source location at this particular column."}, - { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression, + { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Set the breakpoint by address, at the specified address."}, - { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, + { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function name. Can be repeated multiple times to make one breakpoint for multiple names" }, - { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName, + { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName, "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and " "for Objective C this means a full function prototype with class and selector. " "Can be repeated multiple times to make one breakpoint for multiple names." }, - { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, 0, eArgTypeSelector, + { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector, "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." }, - { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, 0, eArgTypeMethod, + { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod, "Set the breakpoint by C++ method names. Can be repeated multiple times to make one breakpoint for multiple methods." }, - { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, 0, eArgTypeRegularExpression, + { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." }, - { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, + { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). " "Can be repeated multiple times to make one breakpoint for multiple symbols." }, - { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypeRegularExpression, + { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files " "specified with the -f option. The -f option can be specified more than once. " "If no source files are specified, uses the current \"default source file\"" }, - { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLanguage, + { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" }, - { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, + { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Set the breakpoint on exception throW." }, - { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, + { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Set the breakpoint on exception catcH." }, - { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, + { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." }, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -1012,16 +1015,16 @@ private: OptionDefinition CommandObjectBreakpointModify::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." }, -{ LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." }, -{ LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."}, -{ LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."}, -{ LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."}, -{ LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."}, -{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."}, -{ LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Enable the breakpoint."}, -{ LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Disable the breakpoint."}, -{ 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." }, +{ LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." }, +{ LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."}, +{ LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."}, +{ LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."}, +{ LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."}, +{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."}, +{ LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."}, +{ LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."}, +{ 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -1078,7 +1081,7 @@ protected: { // No breakpoint selected; enable all currently set breakpoints. target->EnableAllBreakpoints (); - result.AppendMessageWithFormat ("All breakpoints enabled. (%zu breakpoints)\n", num_breakpoints); + result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints); result.SetStatus (eReturnStatusSuccessFinishNoResult); } else @@ -1197,7 +1200,7 @@ protected: { // No breakpoint selected; disable all currently set breakpoints. target->DisableAllBreakpoints (); - result.AppendMessageWithFormat ("All breakpoints disabled. (%zu breakpoints)\n", num_breakpoints); + result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints); result.SetStatus (eReturnStatusSuccessFinishNoResult); } else @@ -1421,21 +1424,21 @@ private: OptionDefinition CommandObjectBreakpointList::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, + { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Show debugger internal breakpoints" }, - { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, + { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Give a brief description of the breakpoint (no location info)."}, // FIXME: We need to add an "internal" command, and then add this sort of thing to it. // But I need to see it for now, and don't want to wait. - { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, + { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Give a full description of the breakpoint and its locations."}, - { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, + { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Explain everything we know about the breakpoint (for debugging debugger bugs)." }, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -1632,13 +1635,13 @@ private: OptionDefinition CommandObjectBreakpointClear::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, + { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the breakpoint by source location in this particular file."}, - { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum, + { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, "Specify the breakpoint by source location at this particular line."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -1699,7 +1702,7 @@ protected: else { target->RemoveAllBreakpoints (); - result.AppendMessageWithFormat ("All breakpoints removed. (%zu %s)\n", num_breakpoints, num_breakpoints > 1 ? "breakpoints" : "breakpoint"); + result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : ""); } result.SetStatus (eReturnStatusSuccessFinishNoResult); } @@ -1843,7 +1846,7 @@ CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *targe if (breakpoint != NULL) { const size_t num_locations = breakpoint->GetNumLocations(); - if (cur_bp_id.GetLocationID() > num_locations) + if (static_cast(cur_bp_id.GetLocationID()) > num_locations) { StreamString id_str; BreakpointID::GetCanonicalReference (&id_str, diff --git a/source/Commands/CommandObjectBreakpointCommand.cpp b/source/Commands/CommandObjectBreakpointCommand.cpp index 532d6cedc83e..fdb87d11900b 100644 --- a/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/source/Commands/CommandObjectBreakpointCommand.cpp @@ -44,9 +44,10 @@ public: CommandObjectBreakpointCommandAdd (CommandInterpreter &interpreter) : CommandObjectParsed (interpreter, "add", - "Add a set of commands to a breakpoint, to be executed whenever the breakpoint is hit.", + "Add a set of commands to a breakpoint, to be executed whenever the breakpoint is hit." + " If no breakpoint is specified, adds the commands to the last created breakpoint.", NULL), - IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand), + IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand), m_options (interpreter) { SetHelpLong ( @@ -193,7 +194,7 @@ one command per line.\n" ); // Define the first (and only) variant of this arg. bp_id_arg.arg_type = eArgTypeBreakpointID; - bp_id_arg.arg_repetition = eArgRepeatPlain; + bp_id_arg.arg_repetition = eArgRepeatOptional; // There is only one variant this argument could be; put it into the argument entry. arg.push_back (bp_id_arg); @@ -228,9 +229,12 @@ one command per line.\n" ); { io_handler.SetIsDone(true); - BreakpointOptions *bp_options = (BreakpointOptions *) io_handler.GetUserData(); - if (bp_options) + std::vector *bp_options_vec = (std::vector *)io_handler.GetUserData(); + for (BreakpointOptions *bp_options : *bp_options_vec) { + if (!bp_options) + continue; + std::unique_ptr data_ap(new BreakpointOptions::CommandData()); if (data_ap.get()) { @@ -239,36 +243,37 @@ one command per line.\n" ); bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp); } } - } void - CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options, + CollectDataForBreakpointCommandCallback (std::vector &bp_options_vec, CommandReturnObject &result) { m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt *this, // IOHandlerDelegate true, // Run IOHandler in async mode - bp_options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions + &bp_options_vec); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions } /// Set a one-liner as the callback for the breakpoint. void - SetBreakpointCommandCallback (BreakpointOptions *bp_options, + SetBreakpointCommandCallback (std::vector &bp_options_vec, const char *oneliner) { - std::unique_ptr data_ap(new BreakpointOptions::CommandData()); - - // It's necessary to set both user_source and script_source to the oneliner. - // The former is used to generate callback description (as in breakpoint command list) - // while the latter is used for Python to interpret during the actual callback. - data_ap->user_source.AppendString (oneliner); - data_ap->script_source.assign (oneliner); - data_ap->stop_on_error = m_options.m_stop_on_error; + for (auto bp_options : bp_options_vec) + { + std::unique_ptr data_ap(new BreakpointOptions::CommandData()); - BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); - bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp); + // It's necessary to set both user_source and script_source to the oneliner. + // The former is used to generate callback description (as in breakpoint command list) + // while the latter is used for Python to interpret during the actual callback. + data_ap->user_source.AppendString (oneliner); + data_ap->script_source.assign (oneliner); + data_ap->stop_on_error = m_options.m_stop_on_error; + BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); + bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp); + } return; } @@ -459,15 +464,11 @@ protected: BreakpointIDList valid_bp_ids; CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids); + m_bp_options_vec.clear(); + if (result.Succeeded()) { const size_t count = valid_bp_ids.GetSize(); - if (count > 1) - { - result.AppendError ("can only add commands to one breakpoint at a time."); - result.SetStatus (eReturnStatusFailed); - return false; - } for (size_t i = 0; i < count; ++i) { @@ -489,50 +490,45 @@ protected: if (bp_loc_sp) bp_options = bp_loc_sp->GetLocationOptions(); } + if (bp_options) + m_bp_options_vec.push_back (bp_options); + } + } - // Skip this breakpoint if bp_options is not good. - if (bp_options == NULL) continue; - - // If we are using script language, get the script interpreter - // in order to set or collect command callback. Otherwise, call - // the methods associated with this object. - if (m_options.m_use_script_language) - { - // Special handling for one-liner specified inline. - if (m_options.m_use_one_liner) - { - m_interpreter.GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options, - m_options.m_one_liner.c_str()); - } - // Special handling for using a Python function by name - // instead of extending the breakpoint callback data structures, we just automatize - // what the user would do manually: make their breakpoint command be a function call - else if (m_options.m_function_name.size()) - { - std::string oneliner("return "); - oneliner += m_options.m_function_name; - oneliner += "(frame, bp_loc, internal_dict)"; - m_interpreter.GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options, - oneliner.c_str()); - } - else - { - m_interpreter.GetScriptInterpreter()->CollectDataForBreakpointCommandCallback (bp_options, - result); - } - } - else - { - // Special handling for one-liner specified inline. - if (m_options.m_use_one_liner) - SetBreakpointCommandCallback (bp_options, - m_options.m_one_liner.c_str()); - else - CollectDataForBreakpointCommandCallback (bp_options, - result); - } + // If we are using script language, get the script interpreter + // in order to set or collect command callback. Otherwise, call + // the methods associated with this object. + if (m_options.m_use_script_language) + { + ScriptInterpreter *script_interp = m_interpreter.GetScriptInterpreter(); + // Special handling for one-liner specified inline. + if (m_options.m_use_one_liner) + { + script_interp->SetBreakpointCommandCallback (m_bp_options_vec, + m_options.m_one_liner.c_str()); + } + else if (m_options.m_function_name.size()) + { + script_interp->SetBreakpointCommandCallbackFunction (m_bp_options_vec, + m_options.m_function_name.c_str()); + } + else + { + script_interp->CollectDataForBreakpointCommandCallback (m_bp_options_vec, + result); } } + else + { + // Special handling for one-liner specified inline. + if (m_options.m_use_one_liner) + SetBreakpointCommandCallback (m_bp_options_vec, + m_options.m_one_liner.c_str()); + else + CollectDataForBreakpointCommandCallback (m_bp_options_vec, + result); + } + } return result.Succeeded(); @@ -540,6 +536,17 @@ protected: private: CommandOptions m_options; + std::vector m_bp_options_vec; // This stores the breakpoint options that we are currently + // collecting commands for. In the CollectData... calls we need + // to hand this off to the IOHandler, which may run asynchronously. + // So we have to have some way to keep it alive, and not leak it. + // Making it an ivar of the command object, which never goes away + // achieves this. Note that if we were able to run + // the same command concurrently in one interpreter we'd have to + // make this "per invocation". But there are many more reasons + // why it is not in general safe to do that in lldb at present, + // so it isn't worthwhile to come up with a more complex mechanism + // to address this particular weakness right now. static const char *g_reader_instructions; }; @@ -562,19 +569,19 @@ g_script_option_enumeration[4] = OptionDefinition CommandObjectBreakpointCommandAdd::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOneLiner, + { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOneLiner, "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, - { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, + { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Specify whether breakpoint command execution should terminate on error." }, - { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, g_script_option_enumeration, 0, eArgTypeNone, + { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, NULL, g_script_option_enumeration, 0, eArgTypeNone, "Specify the language for the commands - if none is specified, the lldb command interpreter will be used."}, - { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, NULL, 0, eArgTypePythonFunction, + { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Give the name of a Python function to run as command for this breakpoint. Be sure to give a module name if appropriate."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -814,7 +821,7 @@ protected: CommandObjectBreakpointCommand::CommandObjectBreakpointCommand (CommandInterpreter &interpreter) : CommandObjectMultiword (interpreter, "command", - "A set of commands for adding, removing and examining bits of code to be executed when the breakpoint is hit (breakpoint 'commmands').", + "A set of commands for adding, removing and examining bits of code to be executed when the breakpoint is hit (breakpoint 'commands').", "command [] ") { CommandObjectSP add_command_object (new CommandObjectBreakpointCommandAdd (interpreter)); diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp index 7bfdec094d6c..7d9bb7dad8fd 100644 --- a/source/Commands/CommandObjectCommands.cpp +++ b/source/Commands/CommandObjectCommands.cpp @@ -226,11 +226,11 @@ protected: OptionDefinition CommandObjectCommandsHistory::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."}, -{ LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)."}, -{ LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."}, -{ LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, NULL, 0, eArgTypeBoolean, "Clears the current command history."}, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."}, +{ LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)."}, +{ LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."}, +{ LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeBoolean, "Clears the current command history."}, +{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -427,10 +427,10 @@ protected: OptionDefinition CommandObjectCommandsSource::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."}, -{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."}, -{ LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true don't echo commands while executing."}, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."}, +{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."}, +{ LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true don't echo commands while executing."}, +{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; #pragma mark CommandObjectCommandsAlias @@ -889,7 +889,7 @@ public: SetHelpLong( "This command allows the user to create powerful regular expression commands\n" "with substitutions. The regular expressions and substitutions are specified\n" -"using the regular exression substitution format of:\n" +"using the regular expression substitution format of:\n" "\n" " s///\n" "\n" @@ -1034,9 +1034,10 @@ protected: Debugger &debugger = m_interpreter.GetDebugger(); const bool multiple_lines = true; // Get multiple lines IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, - "lldb", // Name of input reader for history - "\033[K> ", // Prompt and clear line + "lldb-regex", // Name of input reader for history + "\033[K> ", // Prompt and clear line multiple_lines, + 0, // Don't show line numbers *this)); if (io_handler_sp) @@ -1273,9 +1274,9 @@ private: OptionDefinition CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, 0, eArgTypeNone, "The help text to display for this command."}, -{ LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."}, -{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "The help text to display for this command."}, +{ LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."}, +{ 0 , false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -1547,8 +1548,8 @@ protected: OptionDefinition CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -1795,9 +1796,9 @@ static OptionEnumValueElement g_script_synchro_type[] = OptionDefinition CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."}, - { LLDB_OPT_SET_1, false, "synchronicity", 's', OptionParser::eRequiredArgument, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."}, + { LLDB_OPT_SET_1, false, "synchronicity", 's', OptionParser::eRequiredArgument, NULL, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- diff --git a/source/Commands/CommandObjectDisassemble.cpp b/source/Commands/CommandObjectDisassemble.cpp index f9c683b364ce..8124ce1ef93b 100644 --- a/source/Commands/CommandObjectDisassemble.cpp +++ b/source/Commands/CommandObjectDisassemble.cpp @@ -232,29 +232,29 @@ CommandObjectDisassemble::CommandOptions::GetDefinitions () OptionDefinition CommandObjectDisassemble::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_ALL, false, "bytes" , 'b', OptionParser::eNoArgument , NULL, 0, eArgTypeNone, "Show opcode bytes when disassembling."}, -{ LLDB_OPT_SET_ALL, false, "context" , 'C', OptionParser::eRequiredArgument , NULL, 0, eArgTypeNumLines, "Number of context lines of source to show."}, -{ LLDB_OPT_SET_ALL, false, "mixed" , 'm', OptionParser::eNoArgument , NULL, 0, eArgTypeNone, "Enable mixed source and assembly display."}, -{ LLDB_OPT_SET_ALL, false, "raw" , 'r', OptionParser::eNoArgument , NULL, 0, eArgTypeNone, "Print raw disassembly with no symbol information."}, -{ LLDB_OPT_SET_ALL, false, "plugin" , 'P', OptionParser::eRequiredArgument , NULL, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use."}, -{ LLDB_OPT_SET_ALL, false, "flavor" , 'F', OptionParser::eRequiredArgument , NULL, 0, eArgTypeDisassemblyFlavor, "Name of the disassembly flavor you want to use. " - "Currently the only valid options are default, and for Intel" - " architectures, att and intel."}, -{ LLDB_OPT_SET_ALL, false, "arch" , 'A', OptionParser::eRequiredArgument , NULL, 0, eArgTypeArchitecture,"Specify the architecture to use from cross disassembly."}, +{ LLDB_OPT_SET_ALL, false, "bytes" , 'b', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Show opcode bytes when disassembling."}, +{ LLDB_OPT_SET_ALL, false, "context" , 'C', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypeNumLines, "Number of context lines of source to show."}, +{ LLDB_OPT_SET_ALL, false, "mixed" , 'm', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Enable mixed source and assembly display."}, +{ LLDB_OPT_SET_ALL, false, "raw" , 'r', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Print raw disassembly with no symbol information."}, +{ LLDB_OPT_SET_ALL, false, "plugin" , 'P', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use."}, +{ LLDB_OPT_SET_ALL, false, "flavor" , 'F', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypeDisassemblyFlavor, "Name of the disassembly flavor you want to use. " + "Currently the only valid options are default, and for Intel" + " architectures, att and intel."}, +{ LLDB_OPT_SET_ALL, false, "arch" , 'A', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypeArchitecture,"Specify the architecture to use from cross disassembly."}, { LLDB_OPT_SET_1 | - LLDB_OPT_SET_2 , true , "start-address", 's', OptionParser::eRequiredArgument , NULL, 0, eArgTypeAddressOrExpression,"Address at which to start disassembling."}, -{ LLDB_OPT_SET_1 , false, "end-address" , 'e', OptionParser::eRequiredArgument , NULL, 0, eArgTypeAddressOrExpression, "Address at which to end disassembling."}, + LLDB_OPT_SET_2 , true , "start-address", 's', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypeAddressOrExpression,"Address at which to start disassembling."}, +{ LLDB_OPT_SET_1 , false, "end-address" , 'e', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypeAddressOrExpression, "Address at which to end disassembling."}, { LLDB_OPT_SET_2 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4 | - LLDB_OPT_SET_5 , false, "count" , 'c', OptionParser::eRequiredArgument , NULL, 0, eArgTypeNumLines, "Number of instructions to display."}, -{ LLDB_OPT_SET_3 , false, "name" , 'n', OptionParser::eRequiredArgument , NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, - "Disassemble entire contents of the given function name."}, -{ LLDB_OPT_SET_4 , false, "frame" , 'f', OptionParser::eNoArgument , NULL, 0, eArgTypeNone, "Disassemble from the start of the current frame's function."}, -{ LLDB_OPT_SET_5 , false, "pc" , 'p', OptionParser::eNoArgument , NULL, 0, eArgTypeNone, "Disassemble around the current pc."}, -{ LLDB_OPT_SET_6 , false, "line" , 'l', OptionParser::eNoArgument , NULL, 0, eArgTypeNone, "Disassemble the current frame's current source line instructions if there is debug line table information, else disassemble around the pc."}, -{ LLDB_OPT_SET_7 , false, "address" , 'a', OptionParser::eRequiredArgument , NULL, 0, eArgTypeAddressOrExpression, "Disassemble function containing this address."}, -{ 0 , false, NULL , 0, 0 , NULL, 0, eArgTypeNone, NULL } + LLDB_OPT_SET_5 , false, "count" , 'c', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypeNumLines, "Number of instructions to display."}, +{ LLDB_OPT_SET_3 , false, "name" , 'n', OptionParser::eRequiredArgument , NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, + "Disassemble entire contents of the given function name."}, +{ LLDB_OPT_SET_4 , false, "frame" , 'f', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Disassemble from the start of the current frame's function."}, +{ LLDB_OPT_SET_5 , false, "pc" , 'p', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Disassemble around the current pc."}, +{ LLDB_OPT_SET_6 , false, "line" , 'l', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Disassemble the current frame's current source line instructions if there is debug line table information, else disassemble around the pc."}, +{ LLDB_OPT_SET_7 , false, "address" , 'a', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypeAddressOrExpression, "Disassemble function containing this address."}, +{ 0 , false, NULL , 0, 0 , NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -370,6 +370,7 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result) } else { + std::vector ranges; AddressRange range; StackFrame *frame = m_exe_ctx.GetFramePtr(); if (m_options.frame_line) @@ -425,6 +426,7 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result) // Disassembling at the PC always disassembles some number of instructions (not the whole function). m_options.num_instructions = DEFAULT_DISASM_NUM_INS; } + ranges.push_back(range); } else { @@ -441,49 +443,75 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result) } range.SetByteSize (m_options.end_addr - m_options.start_addr); } + ranges.push_back(range); } else { if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS - && target - && !target->GetSectionLoadList().IsEmpty()) + && target) { - bool failed = false; - Address symbol_containing_address; - if (target->GetSectionLoadList().ResolveLoadAddress (m_options.symbol_containing_addr, symbol_containing_address)) + if (!target->GetSectionLoadList().IsEmpty()) { - ModuleSP module_sp (symbol_containing_address.GetModule()); - SymbolContext sc; - bool resolve_tail_call_address = true; // PC can be one past the address range of the function. - module_sp->ResolveSymbolContextForAddress (symbol_containing_address, eSymbolContextEverything, sc, - resolve_tail_call_address); - if (sc.function || sc.symbol) + bool failed = false; + Address symbol_containing_address; + if (target->GetSectionLoadList().ResolveLoadAddress (m_options.symbol_containing_addr, symbol_containing_address)) { - sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range); + ModuleSP module_sp (symbol_containing_address.GetModule()); + SymbolContext sc; + bool resolve_tail_call_address = true; // PC can be one past the address range of the function. + module_sp->ResolveSymbolContextForAddress (symbol_containing_address, eSymbolContextEverything, sc, + resolve_tail_call_address); + if (sc.function || sc.symbol) + { + sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range); + } + else + { + failed = true; + } } else { failed = true; } + if (failed) + { + result.AppendErrorWithFormat ("Could not find function bounds for address 0x%" PRIx64 "\n", m_options.symbol_containing_addr); + result.SetStatus (eReturnStatusFailed); + return false; + } + ranges.push_back(range); } else { - failed = true; - } - if (failed) - { - result.AppendErrorWithFormat ("Could not find function bounds for address 0x%" PRIx64 "\n", m_options.symbol_containing_addr); - result.SetStatus (eReturnStatusFailed); - return false; + for (lldb::ModuleSP module_sp : target->GetImages().Modules()) + { + lldb::addr_t file_addr = m_options.symbol_containing_addr; + Address file_address; + if (module_sp->ResolveFileAddress(file_addr, file_address)) + { + SymbolContext sc; + bool resolve_tail_call_address = true; // PC can be one past the address range of the function. + module_sp->ResolveSymbolContextForAddress (file_address, eSymbolContextEverything, sc, resolve_tail_call_address); + if (sc.function || sc.symbol) + { + sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range); + ranges.push_back(range); + } + } + } + } } } } } + else + ranges.push_back(range); if (m_options.num_instructions != 0) { - if (!range.GetBaseAddress().IsValid()) + if (ranges.size() == 0) { // The default action is to disassemble the current frame function. if (frame) @@ -504,29 +532,38 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result) return false; } } - - if (Disassembler::Disassemble (m_interpreter.GetDebugger(), - m_options.arch, - plugin_name, - flavor_string, - m_exe_ctx, - range.GetBaseAddress(), - m_options.num_instructions, - m_options.show_mixed ? m_options.num_lines_context : 0, - options, - result.GetOutputStream())) - { - result.SetStatus (eReturnStatusSuccessFinishResult); - } - else + + bool print_sc_header = ranges.size() > 1; + for (AddressRange cur_range : ranges) { - result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", m_options.start_addr); - result.SetStatus (eReturnStatusFailed); + if (Disassembler::Disassemble (m_interpreter.GetDebugger(), + m_options.arch, + plugin_name, + flavor_string, + m_exe_ctx, + cur_range.GetBaseAddress(), + m_options.num_instructions, + m_options.show_mixed ? m_options.num_lines_context : 0, + options, + result.GetOutputStream())) + { + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + if (m_options.start_addr != LLDB_INVALID_ADDRESS) + result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", m_options.start_addr); + else if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS) + result.AppendErrorWithFormat ("Failed to disassemble memory in function at 0x%8.8" PRIx64 ".\n", m_options.symbol_containing_addr); + result.SetStatus (eReturnStatusFailed); + } } + if (print_sc_header) + result.AppendMessage("\n"); } else { - if (!range.GetBaseAddress().IsValid()) + if (ranges.size() == 0) { // The default action is to disassemble the current frame function. if (frame) @@ -548,27 +585,35 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result) result.SetStatus (eReturnStatusFailed); return false; } + ranges.push_back(range); } - if (range.GetByteSize() == 0) - range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE); - - if (Disassembler::Disassemble (m_interpreter.GetDebugger(), - m_options.arch, - plugin_name, - flavor_string, - m_exe_ctx, - range, - m_options.num_instructions, - m_options.show_mixed ? m_options.num_lines_context : 0, - options, - result.GetOutputStream())) + + bool print_sc_header = ranges.size() > 1; + for (AddressRange cur_range : ranges) { - result.SetStatus (eReturnStatusSuccessFinishResult); - } - else - { - result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", m_options.start_addr); - result.SetStatus (eReturnStatusFailed); + if (cur_range.GetByteSize() == 0) + cur_range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE); + + if (Disassembler::Disassemble (m_interpreter.GetDebugger(), + m_options.arch, + plugin_name, + flavor_string, + m_exe_ctx, + cur_range, + m_options.num_instructions, + m_options.show_mixed ? m_options.num_lines_context : 0, + options, + result.GetOutputStream())) + { + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", m_options.start_addr); + result.SetStatus (eReturnStatusFailed); + } + if (print_sc_header) + result.AppendMessage("\n"); } } } diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp index c772a2e58912..079c62ddfdff 100644 --- a/source/Commands/CommandObjectExpression.cpp +++ b/source/Commands/CommandObjectExpression.cpp @@ -34,6 +34,7 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" using namespace lldb; @@ -59,19 +60,19 @@ static OptionEnumValueElement g_description_verbosity_type[] = OptionDefinition CommandObjectExpression::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."}, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"}, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger, "Timeout value (in microseconds) for running the expression."}, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, or raises a signal. Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."}, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug", 'g', OptionParser::eNoArgument , NULL, 0, eArgTypeNone, "When specified, debug the JIT code by setting a breakpoint on the first instruction and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."}, - { LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, g_description_verbosity_type, 0, eArgTypeDescriptionVerbosity, "How verbose should the output of this expression be, if the object description is asked for."}, + { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."}, + { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"}, + { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Timeout value (in microseconds) for running the expression."}, + { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, or raises a signal. Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."}, + { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug", 'g', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "When specified, debug the JIT code by setting a breakpoint on the first instruction and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."}, + { LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, NULL, g_description_verbosity_type, 0, eArgTypeDescriptionVerbosity, "How verbose should the output of this expression be, if the object description is asked for."}, }; uint32_t CommandObjectExpression::CommandOptions::GetNumDefinitions () { - return sizeof(g_option_table)/sizeof(OptionDefinition); + return llvm::array_lengthof(g_option_table); } Error @@ -173,7 +174,7 @@ CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpret } else { - ignore_breakpoints = false; + ignore_breakpoints = true; unwind_on_error = true; } @@ -205,7 +206,7 @@ CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interprete { SetHelpLong( "Timeouts:\n\ - If the expression can be evaluated statically (without runnning code) then it will be.\n\ + If the expression can be evaluated statically (without running code) then it will be.\n\ Otherwise, by default the expression will run on the current thread with a short timeout:\n\ currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted\n\ and resumed with all threads running. You can use the -a option to disable retrying on all\n\ @@ -217,6 +218,15 @@ User defined variables:\n\ your user defined variable is a $, then the variable's value will be available in future\n\ expressions, otherwise it will just be available in the current expression.\n\ \n\ +\n\ +Continuing evaluation after a breakpoint:\n\ + If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once\n\ + you are done with your investigation, you can either remove the expression execution frames\n\ + from the stack with \"thread return -x\" or if you are still interested in the expression result\n\ + you can issue the \"continue\" command and the expression evaluation will complete and the\n\ + expression result will be available using the \"thread.completed-expression\" key in the thread\n\ + format.\n\ +\n\ Examples: \n\ \n\ expr my_struct->a = my_array[3] \n\ @@ -277,8 +287,6 @@ CommandObjectExpression::EvaluateExpression { lldb::ValueObjectSP result_valobj_sp; - ExecutionResults exe_results; - bool keep_in_memory = true; EvaluateExpressionOptions options; @@ -290,15 +298,19 @@ CommandObjectExpression::EvaluateExpression options.SetTryAllThreads(m_command_options.try_all_threads); options.SetDebug(m_command_options.debug); + // If there is any chance we are going to stop and want to see + // what went wrong with our expression, we should generate debug info + if (!m_command_options.ignore_breakpoints || + !m_command_options.unwind_on_error) + options.SetGenerateDebugInfo(true); + if (m_command_options.timeout > 0) options.SetTimeoutUsec(m_command_options.timeout); else options.SetTimeoutUsec(0); - - exe_results = target->EvaluateExpression (expr, - exe_ctx.GetFramePtr(), - result_valobj_sp, - options); + + target->EvaluateExpression(expr, exe_ctx.GetFramePtr(), + result_valobj_sp, options); if (result_valobj_sp) { @@ -406,6 +418,30 @@ CommandObjectExpression::IOHandlerLinesUpdated (IOHandler &io_handler, return LineStatus::Success; } +void +CommandObjectExpression::GetMultilineExpression () +{ + m_expr_lines.clear(); + m_expr_line_count = 0; + + Debugger &debugger = GetCommandInterpreter().GetDebugger(); + const bool multiple_lines = true; // Get multiple lines + IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, + "lldb-expr", // Name of input reader for history + NULL, // No prompt + multiple_lines, + 1, // Show line numbers starting at 1 + *this)); + + StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile()); + if (output_sp) + { + output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n"); + output_sp->Flush(); + } + debugger.PushIOHandler(io_handler_sp); +} + bool CommandObjectExpression::DoExecute ( @@ -419,24 +455,7 @@ CommandObjectExpression::DoExecute if (command[0] == '\0') { - m_expr_lines.clear(); - m_expr_line_count = 0; - - Debugger &debugger = GetCommandInterpreter().GetDebugger(); - const bool multiple_lines = true; // Get multiple lines - IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, - "lldb-expr", // Name of input reader for history - NULL, // No prompt - multiple_lines, - *this)); - - StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile()); - if (output_sp) - { - output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n"); - output_sp->Flush(); - } - debugger.PushIOHandler(io_handler_sp); + GetMultilineExpression (); return result.Succeeded(); } @@ -475,6 +494,13 @@ CommandObjectExpression::DoExecute result.SetStatus (eReturnStatusFailed); return false; } + + // No expression following options + if (expr == NULL || expr[0] == '\0') + { + GetMultilineExpression (); + return result.Succeeded(); + } } } diff --git a/source/Commands/CommandObjectExpression.h b/source/Commands/CommandObjectExpression.h index c943f0e8023d..168140d7fe56 100644 --- a/source/Commands/CommandObjectExpression.h +++ b/source/Commands/CommandObjectExpression.h @@ -96,6 +96,9 @@ protected: Stream *output_stream, Stream *error_stream, CommandReturnObject *result = NULL); + + void + GetMultilineExpression (); OptionGroupOptions m_option_group; OptionGroupFormat m_format_options; diff --git a/source/Commands/CommandObjectFrame.cpp b/source/Commands/CommandObjectFrame.cpp index 0ef973261508..ce540a5c3100 100644 --- a/source/Commands/CommandObjectFrame.cpp +++ b/source/Commands/CommandObjectFrame.cpp @@ -204,7 +204,7 @@ protected: if (m_options.relative_frame_offset < 0) { - if (frame_idx >= -m_options.relative_frame_offset) + if (static_cast(frame_idx) >= -m_options.relative_frame_offset) frame_idx += m_options.relative_frame_offset; else { @@ -224,7 +224,7 @@ protected: // I don't want "up 20" where "20" takes you past the top of the stack to produce // an error, but rather to just go to the top. So I have to count the stack here... const uint32_t num_frames = thread->GetStackFrameCount(); - if (num_frames - frame_idx > m_options.relative_frame_offset) + if (static_cast(num_frames - frame_idx) > m_options.relative_frame_offset) frame_idx += m_options.relative_frame_offset; else { @@ -291,8 +291,8 @@ protected: OptionDefinition CommandObjectFrameSelect::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_1, false, "relative", 'r', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOffset, "A relative frame index offset from the current frame index."}, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_1, false, "relative", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset, "A relative frame index offset from the current frame index."}, +{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; #pragma mark CommandObjectFrameVariable @@ -471,7 +471,7 @@ protected: if (regex.GetErrorAsCString(regex_error, sizeof(regex_error))) result.GetErrorStream().Printf ("error: %s\n", regex_error); else - result.GetErrorStream().Printf ("error: unkown regex error when compiling '%s'\n", name_cstr); + result.GetErrorStream().Printf ("error: unknown regex error when compiling '%s'\n", name_cstr); } } else // No regex, either exact variable names or variable expressions. diff --git a/source/Commands/CommandObjectHelp.cpp b/source/Commands/CommandObjectHelp.cpp index bd0c3938c702..f73d9d23b574 100644 --- a/source/Commands/CommandObjectHelp.cpp +++ b/source/Commands/CommandObjectHelp.cpp @@ -54,9 +54,9 @@ CommandObjectHelp::~CommandObjectHelp() OptionDefinition CommandObjectHelp::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "show-aliases", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Show aliases in the command list."}, - { LLDB_OPT_SET_ALL, false, "hide-user-commands", 'u', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Hide user-defined commands from the list."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { 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-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 } }; bool diff --git a/source/Commands/CommandObjectLog.cpp b/source/Commands/CommandObjectLog.cpp index 2d815846a607..7d32cc6d08a5 100644 --- a/source/Commands/CommandObjectLog.cpp +++ b/source/Commands/CommandObjectLog.cpp @@ -215,16 +215,16 @@ protected: OptionDefinition CommandObjectLogEnable::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFilename, "Set the destination file to log to."}, -{ LLDB_OPT_SET_1, false, "threadsafe", 't', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Enable thread safe logging to avoid interweaved log lines." }, -{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Enable verbose logging." }, -{ LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Enable debug logging." }, -{ LLDB_OPT_SET_1, false, "sequence", 's', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Prepend all log lines with an increasing integer sequence id." }, -{ LLDB_OPT_SET_1, false, "timestamp", 'T', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Prepend all log lines with a timestamp." }, -{ LLDB_OPT_SET_1, false, "pid-tid", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Prepend all log lines with the process and thread ID that generates the log line." }, -{ LLDB_OPT_SET_1, false, "thread-name",'n', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Prepend all log lines with the thread name for the thread that generates the log line." }, -{ LLDB_OPT_SET_1, false, "stack", 'S', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Append a stack backtrace to each log line." }, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Set the destination file to log to."}, +{ LLDB_OPT_SET_1, false, "threadsafe", 't', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable thread safe logging to avoid interweaved log lines." }, +{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable verbose logging." }, +{ LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable debug logging." }, +{ LLDB_OPT_SET_1, false, "sequence", 's', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Prepend all log lines with an increasing integer sequence id." }, +{ LLDB_OPT_SET_1, false, "timestamp", 'T', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Prepend all log lines with a timestamp." }, +{ LLDB_OPT_SET_1, false, "pid-tid", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Prepend all log lines with the process and thread ID that generates the log line." }, +{ LLDB_OPT_SET_1, false, "thread-name",'n', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Prepend all log lines with the thread name for the thread that generates the log line." }, +{ LLDB_OPT_SET_1, false, "stack", 'S', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Append a stack backtrace to each log line." }, +{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; class CommandObjectLogDisable : public CommandObjectParsed diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp index cb7398fb9554..bfbb296158a9 100644 --- a/source/Commands/CommandObjectMemory.cpp +++ b/source/Commands/CommandObjectMemory.cpp @@ -42,12 +42,12 @@ using namespace lldb_private; static OptionDefinition g_option_table[] = { - { LLDB_OPT_SET_1, false, "num-per-line" ,'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeNumberPerLine ,"The number of items per line to display."}, - { LLDB_OPT_SET_2, false, "binary" ,'b', OptionParser::eNoArgument , NULL, 0, eArgTypeNone ,"If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that uses the format, size, count and number per line settings."}, - { LLDB_OPT_SET_3, true , "type" ,'t', OptionParser::eRequiredArgument, NULL, 0, eArgTypeNone ,"The name of a type to view memory as."}, + { LLDB_OPT_SET_1, false, "num-per-line" ,'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNumberPerLine ,"The number of items per line to display."}, + { LLDB_OPT_SET_2, false, "binary" ,'b', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone ,"If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that uses the format, size, count and number per line settings."}, + { LLDB_OPT_SET_3, true , "type" ,'t', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone ,"The name of a type to view memory as."}, { LLDB_OPT_SET_1| LLDB_OPT_SET_2| - LLDB_OPT_SET_3, false, "force" ,'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone ,"Necessary if reading over target.max-memory-read-size bytes."}, + LLDB_OPT_SET_3, false, "force" ,'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone ,"Necessary if reading over target.max-memory-read-size bytes."}, }; @@ -651,7 +651,7 @@ protected: } else if (m_format_options.GetCountValue().OptionWasSet()) { - result.AppendErrorWithFormat("specify either the end address (0x%" PRIx64 ") or the count (--count %zu), not both.\n", end_addr, item_count); + result.AppendErrorWithFormat("specify either the end address (0x%" PRIx64 ") or the count (--count %" PRIu64 "), not both.\n", end_addr, (uint64_t)item_count); result.SetStatus(eReturnStatusFailed); return false; } @@ -685,7 +685,7 @@ protected: data_sp.reset (new DataBufferHeap (total_byte_size, '\0')); if (data_sp->GetBytes() == NULL) { - result.AppendErrorWithFormat ("can't allocate 0x%zx bytes for the memory read buffer, specify a smaller size to read", total_byte_size); + result.AppendErrorWithFormat ("can't allocate 0x%" PRIx32 " bytes for the memory read buffer, specify a smaller size to read", (uint32_t)total_byte_size); result.SetStatus(eReturnStatusFailed); return false; } @@ -708,7 +708,7 @@ protected: } if (bytes_read < total_byte_size) - result.AppendWarningWithFormat("Not all bytes (%zu/%zu) were able to be read from 0x%" PRIx64 ".\n", bytes_read, total_byte_size, addr); + result.AppendWarningWithFormat("Not all bytes (%" PRIu64 "/%" PRIu64 ") were able to be read from 0x%" PRIx64 ".\n", (uint64_t)bytes_read, (uint64_t)total_byte_size, addr); } else { @@ -878,7 +878,7 @@ protected: // here we passed a count, and it was not 1 // so we have a byte_size and a count // we could well multiply those, but instead let's just fail - result.AppendErrorWithFormat("reading memory as characters of size %zu is not supported", item_byte_size); + result.AppendErrorWithFormat("reading memory as characters of size %" PRIu64 " is not supported", (uint64_t)item_byte_size); result.SetStatus(eReturnStatusFailed); return false; } @@ -917,10 +917,10 @@ protected: OptionDefinition g_memory_find_option_table[] = { - { LLDB_OPT_SET_1, false, "expression", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeExpression, "Evaluate an expression to obtain a byte pattern."}, - { LLDB_OPT_SET_2, false, "string", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Use text to find a byte pattern."}, - { LLDB_OPT_SET_1|LLDB_OPT_SET_2, false, "count", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, "How many times to perform the search."}, - { LLDB_OPT_SET_1|LLDB_OPT_SET_2, false, "dump-offset", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOffset, "When dumping memory for a match, an offset from the match location to start dumping from."}, + { LLDB_OPT_SET_1, false, "expression", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "Evaluate an expression to obtain a byte pattern."}, + { LLDB_OPT_SET_2, false, "string", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Use text to find a byte pattern."}, + { LLDB_OPT_SET_1|LLDB_OPT_SET_2, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "How many times to perform the search."}, + { LLDB_OPT_SET_1|LLDB_OPT_SET_2, false, "dump-offset", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset, "When dumping memory for a match, an offset from the match location to start dumping from."}, }; //---------------------------------------------------------------------- @@ -1223,8 +1223,8 @@ protected: OptionDefinition g_memory_write_option_table[] = { -{ LLDB_OPT_SET_1, true, "infile", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFilename, "Write memory using the contents of a file."}, -{ LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOffset, "Start writng bytes from an offset within the input file."}, +{ LLDB_OPT_SET_1, true, "infile", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Write memory using the contents of a file."}, +{ LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset, "Start writing bytes from an offset within the input file."}, }; //---------------------------------------------------------------------- @@ -1536,7 +1536,7 @@ protected: } else if (!UIntValueIsValidForSize (uval64, item_byte_size)) { - result.AppendErrorWithFormat ("Value 0x%" PRIx64 " is too large to fit in a %zu byte unsigned integer value.\n", uval64, item_byte_size); + result.AppendErrorWithFormat("Value 0x%" PRIx64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size); result.SetStatus(eReturnStatusFailed); return false; } @@ -1564,7 +1564,7 @@ protected: } else if (!UIntValueIsValidForSize (uval64, item_byte_size)) { - result.AppendErrorWithFormat ("Value 0x%" PRIx64 " is too large to fit in a %zu byte unsigned integer value.\n", uval64, item_byte_size); + result.AppendErrorWithFormat("Value 0x%" PRIx64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size); result.SetStatus(eReturnStatusFailed); return false; } @@ -1604,7 +1604,7 @@ protected: } else if (!SIntValueIsValidForSize (sval64, item_byte_size)) { - result.AppendErrorWithFormat ("Value %" PRIi64 " is too large or small to fit in a %zu byte signed integer value.\n", sval64, item_byte_size); + result.AppendErrorWithFormat ("Value %" PRIi64 " is too large or small to fit in a %" PRIu64 " byte signed integer value.\n", sval64, (uint64_t)item_byte_size); result.SetStatus(eReturnStatusFailed); return false; } @@ -1621,7 +1621,7 @@ protected: } else if (!UIntValueIsValidForSize (uval64, item_byte_size)) { - result.AppendErrorWithFormat ("Value %" PRIu64 " is too large to fit in a %zu byte unsigned integer value.\n", uval64, item_byte_size); + result.AppendErrorWithFormat ("Value %" PRIu64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size); result.SetStatus(eReturnStatusFailed); return false; } @@ -1638,7 +1638,7 @@ protected: } else if (!UIntValueIsValidForSize (uval64, item_byte_size)) { - result.AppendErrorWithFormat ("Value %" PRIo64 " is too large to fit in a %zu byte unsigned integer value.\n", uval64, item_byte_size); + result.AppendErrorWithFormat ("Value %" PRIo64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size); result.SetStatus(eReturnStatusFailed); return false; } diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp index 5e842bf848a3..9998dbdccdad 100644 --- a/source/Commands/CommandObjectPlatform.cpp +++ b/source/Commands/CommandObjectPlatform.cpp @@ -21,6 +21,7 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandOptionValidators.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionGroupFile.h" #include "lldb/Interpreter/OptionGroupPlatform.h" @@ -64,20 +65,19 @@ ParsePermissionString(const char* permissions) static OptionDefinition g_permissions_options[] = { - { LLDB_OPT_SET_ALL, false, "permissions-value", 'v', OptionParser::eRequiredArgument, NULL, 0, eArgTypePermissionsNumber , "Give out the numeric value for permissions (e.g. 757)" }, - { LLDB_OPT_SET_ALL, false, "permissions-string",'s', OptionParser::eRequiredArgument, NULL, 0, eArgTypePermissionsString , "Give out the string value for permissions (e.g. rwxr-xr--)." }, - { LLDB_OPT_SET_ALL, false, "user-read", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow user to read." }, - { LLDB_OPT_SET_ALL, false, "user-write", 'w', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow user to write." }, - { LLDB_OPT_SET_ALL, false, "user-exec", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow user to execute." }, - - { LLDB_OPT_SET_ALL, false, "group-read", 'R', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow group to read." }, - { LLDB_OPT_SET_ALL, false, "group-write", 'W', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow group to write." }, - { LLDB_OPT_SET_ALL, false, "group-exec", 'X', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow group to execute." }, - - { LLDB_OPT_SET_ALL, false, "world-read", 'd', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow world to read." }, - { LLDB_OPT_SET_ALL, false, "world-write", 't', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow world to write." }, - { LLDB_OPT_SET_ALL, false, "world-exec", 'e', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow world to execute." }, - + { LLDB_OPT_SET_ALL, false, "permissions-value", 'v', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePermissionsNumber , "Give out the numeric value for permissions (e.g. 757)" }, + { LLDB_OPT_SET_ALL, false, "permissions-string", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePermissionsString , "Give out the string value for permissions (e.g. rwxr-xr--)." }, + { LLDB_OPT_SET_ALL, false, "user-read", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow user to read." }, + { LLDB_OPT_SET_ALL, false, "user-write", 'w', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow user to write." }, + { LLDB_OPT_SET_ALL, false, "user-exec", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow user to execute." }, + + { LLDB_OPT_SET_ALL, false, "group-read", 'R', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow group to read." }, + { LLDB_OPT_SET_ALL, false, "group-write", 'W', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow group to write." }, + { LLDB_OPT_SET_ALL, false, "group-exec", 'X', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow group to execute." }, + + { LLDB_OPT_SET_ALL, false, "world-read", 'd', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow world to read." }, + { LLDB_OPT_SET_ALL, false, "world-write", 't', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow world to write." }, + { LLDB_OPT_SET_ALL, false, "world-exec", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone , "Allow world to execute." }, }; class OptionPermissions : public lldb_private::OptionGroup @@ -894,9 +894,9 @@ protected: OptionDefinition CommandObjectPlatformFRead::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "offset" , 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeIndex , "Offset into the file at which to start reading." }, - { LLDB_OPT_SET_1, false, "count" , 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount , "Number of bytes to read from the file." }, - { 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL } + { LLDB_OPT_SET_1, false, "offset" , 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeIndex , "Offset into the file at which to start reading." }, + { LLDB_OPT_SET_1, false, "count" , 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount , "Number of bytes to read from the file." }, + { 0 , false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone , NULL } }; @@ -1020,9 +1020,9 @@ protected: OptionDefinition CommandObjectPlatformFWrite::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "offset" , 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeIndex , "Offset into the file at which to start reading." }, - { LLDB_OPT_SET_1, false, "data" , 'd', OptionParser::eRequiredArgument, NULL, 0, eArgTypeValue , "Text to write to the file." }, - { 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL } + { LLDB_OPT_SET_1, false, "offset" , 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeIndex , "Offset into the file at which to start reading." }, + { LLDB_OPT_SET_1, false, "data" , 'd', OptionParser::eRequiredArgument , NULL, NULL, 0, eArgTypeValue , "Text to write to the file." }, + { 0 , false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone , NULL } }; class CommandObjectPlatformFile : public CommandObjectMultiword @@ -1645,24 +1645,29 @@ protected: CommandOptions m_options; }; +namespace +{ + PosixPlatformCommandOptionValidator g_posix_validator; +} + OptionDefinition CommandObjectPlatformProcessList::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_1 , false, "pid" , 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypePid , "List the process info for a specific process ID." }, -{ LLDB_OPT_SET_2 , true , "name" , 'n', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that match a string." }, -{ LLDB_OPT_SET_3 , true , "ends-with" , 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that end with a string." }, -{ LLDB_OPT_SET_4 , true , "starts-with", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that start with a string." }, -{ LLDB_OPT_SET_5 , true , "contains" , 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that contain a string." }, -{ LLDB_OPT_SET_6 , true , "regex" , 'r', OptionParser::eRequiredArgument, NULL, 0, eArgTypeRegularExpression, "Find processes with executable basenames that match a regular expression." }, -{ LLDB_OPT_SET_FROM_TO(2, 6), false, "parent" , 'P', OptionParser::eRequiredArgument, NULL, 0, eArgTypePid , "Find processes that have a matching parent process ID." }, -{ LLDB_OPT_SET_FROM_TO(2, 6), false, "uid" , 'u', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching user ID." }, -{ LLDB_OPT_SET_FROM_TO(2, 6), false, "euid" , 'U', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective user ID." }, -{ LLDB_OPT_SET_FROM_TO(2, 6), false, "gid" , 'g', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching group ID." }, -{ LLDB_OPT_SET_FROM_TO(2, 6), false, "egid" , 'G', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective group ID." }, -{ LLDB_OPT_SET_FROM_TO(2, 6), false, "arch" , 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." }, -{ LLDB_OPT_SET_FROM_TO(1, 6), false, "show-args" , 'A', OptionParser::eNoArgument , NULL, 0, eArgTypeNone , "Show process arguments instead of the process executable basename." }, -{ LLDB_OPT_SET_FROM_TO(1, 6), false, "verbose" , 'v', OptionParser::eNoArgument , NULL, 0, eArgTypeNone , "Enable verbose output." }, -{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL } +{ LLDB_OPT_SET_1 , false, "pid" , 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePid , "List the process info for a specific process ID." }, +{ LLDB_OPT_SET_2 , true , "name" , 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that match a string." }, +{ LLDB_OPT_SET_3 , true , "ends-with" , 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that end with a string." }, +{ LLDB_OPT_SET_4 , true , "starts-with", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that start with a string." }, +{ LLDB_OPT_SET_5 , true , "contains" , 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that contain a string." }, +{ LLDB_OPT_SET_6 , true , "regex" , 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, "Find processes with executable basenames that match a regular expression." }, +{ LLDB_OPT_SET_FROM_TO(2, 6), false, "parent" , 'P', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePid , "Find processes that have a matching parent process ID." }, +{ LLDB_OPT_SET_FROM_TO(2, 6), false, "uid" , 'u', OptionParser::eRequiredArgument, &g_posix_validator, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching user ID." }, +{ LLDB_OPT_SET_FROM_TO(2, 6), false, "euid" , 'U', OptionParser::eRequiredArgument, &g_posix_validator, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective user ID." }, +{ LLDB_OPT_SET_FROM_TO(2, 6), false, "gid" , 'g', OptionParser::eRequiredArgument, &g_posix_validator, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching group ID." }, +{ LLDB_OPT_SET_FROM_TO(2, 6), false, "egid" , 'G', OptionParser::eRequiredArgument, &g_posix_validator, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective group ID." }, +{ LLDB_OPT_SET_FROM_TO(2, 6), false, "arch" , 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." }, +{ LLDB_OPT_SET_FROM_TO(1, 6), false, "show-args" , 'A', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone , "Show process arguments instead of the process executable basename." }, +{ LLDB_OPT_SET_FROM_TO(1, 6), false, "verbose" , 'v', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone , "Enable verbose output." }, +{ 0 , false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone , NULL } }; //---------------------------------------------------------------------- @@ -1965,11 +1970,11 @@ protected: OptionDefinition CommandObjectPlatformProcessAttach::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, - { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, - { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, - { LLDB_OPT_SET_2, false, "waitfor",'w', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Wait for the the process with to launch."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_ALL, false, "plugin", 'P' , OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, + { LLDB_OPT_SET_1, false, "pid", 'p' , OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, + { LLDB_OPT_SET_2, false, "name", 'n' , OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, + { LLDB_OPT_SET_2, false, "waitfor", 'w' , OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Wait for the the process with to launch."}, + { 0, false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -2192,8 +2197,8 @@ public: OptionDefinition CommandObjectPlatformShell::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "timeout", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeValue, "Seconds to wait for the remote host to finish running the command."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_ALL, false, "timeout", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeValue, "Seconds to wait for the remote host to finish running the command."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp index 49a392286c6a..6536c6ef1693 100644 --- a/source/Commands/CommandObjectProcess.cpp +++ b/source/Commands/CommandObjectProcess.cpp @@ -20,6 +20,7 @@ #include "lldb/Breakpoint/BreakpointSite.h" #include "lldb/Core/State.h" #include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" #include "lldb/Host/Host.h" #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/Options.h" @@ -204,8 +205,28 @@ protected: const char *target_settings_argv0 = target->GetArg0(); - if (target->GetDisableASLR()) + // Determine whether we will disable ASLR or leave it in the default state (i.e. enabled if the platform supports it). + // First check if the process launch options explicitly turn on/off disabling ASLR. If so, use that setting; + // otherwise, use the 'settings target.disable-aslr' setting. + bool disable_aslr = false; + if (m_options.disable_aslr != eLazyBoolCalculate) + { + // The user specified an explicit setting on the process launch line. Use it. + disable_aslr = (m_options.disable_aslr == eLazyBoolYes); + } + else + { + // The user did not explicitly specify whether to disable ASLR. Fall back to the target.disable-aslr setting. + disable_aslr = target->GetDisableASLR (); + } + + if (disable_aslr) m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR); + else + m_options.launch_info.GetFlags().Clear (eLaunchFlagDisableASLR); + + if (target->GetDetachOnError()) + m_options.launch_info.GetFlags().Set (eLaunchFlagDetachOnError); if (target->GetDisableSTDIO()) m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO); @@ -532,6 +553,9 @@ protected: if (error.Success()) { + // 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()); @@ -553,7 +577,11 @@ protected: } else { - result.AppendError ("attach failed: process did not stop (no such process or permission problem?)"); + 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); } @@ -617,13 +645,13 @@ protected: OptionDefinition CommandObjectProcessAttach::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_ALL, false, "continue",'c', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Immediately continue the process once attached."}, -{ LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, -{ LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, -{ LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, -{ LLDB_OPT_SET_2, false, "include-existing", 'i', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Include existing processes when doing attach -w."}, -{ LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Wait for the process with to launch."}, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_ALL, false, "continue",'c', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Immediately continue the process once attached."}, +{ LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, +{ LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, +{ LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, +{ LLDB_OPT_SET_2, false, "include-existing", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Include existing processes when doing attach -w."}, +{ LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Wait for the process with to launch."}, +{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -758,13 +786,20 @@ protected: // Set the actions that the threads should each take when resuming for (uint32_t idx=0; idxGetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning); + const bool override_suspend = false; + process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning, override_suspend); } } - + Error error(process->Resume()); + if (error.Success()) { + // There is a race condition where this thread will return up the call stack to the main command + // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has + // a chance to call PushProcessIOHandler(). + process->SyncIOHandler(2000); + result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID()); if (synchronous_execution) { @@ -807,9 +842,9 @@ protected: OptionDefinition CommandObjectProcessContinue::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger, +{ LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Ignore crossings of the breakpoint (if it exists) for the currently selected thread."}, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -911,7 +946,6 @@ protected: DoExecute (Args& command, CommandReturnObject &result) { Process *process = m_exe_ctx.GetProcessPtr(); - result.AppendMessageWithFormat ("Detaching from process %" PRIu64 "\n", process->GetID()); // FIXME: This will be a Command Option: bool keep_stopped; if (m_options.m_keep_stopped == eLazyBoolCalculate) @@ -947,8 +981,8 @@ protected: OptionDefinition CommandObjectProcessDetach::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_1, false, "keep-stopped", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." }, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_1, false, "keep-stopped", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." }, +{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -1119,8 +1153,8 @@ protected: OptionDefinition CommandObjectProcessConnect::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, - { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, + { 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -1482,6 +1516,71 @@ protected: } }; +//------------------------------------------------------------------------- +// CommandObjectProcessSaveCore +//------------------------------------------------------------------------- +#pragma mark CommandObjectProcessSaveCore + +class CommandObjectProcessSaveCore : public CommandObjectParsed +{ +public: + + CommandObjectProcessSaveCore (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "process save-core", + "Save the current process as a core file using an appropriate file type.", + "process save-core FILE", + eFlagRequiresProcess | + eFlagTryTargetAPILock | + eFlagProcessMustBeLaunched) + { + } + + ~CommandObjectProcessSaveCore () + { + } + +protected: + bool + DoExecute (Args& command, + CommandReturnObject &result) + { + ProcessSP process_sp = m_exe_ctx.GetProcessSP(); + if (process_sp) + { + if (command.GetArgumentCount() == 1) + { + FileSpec output_file(command.GetArgumentAtIndex(0), false); + Error error = PluginManager::SaveCore(process_sp, output_file); + if (error.Success()) + { + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + result.AppendErrorWithFormat ("Failed to save core file for process: %s\n", error.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + result.AppendErrorWithFormat ("'%s' takes one arguments:\nUsage: %s\n", + m_cmd_name.c_str(), + m_cmd_syntax.c_str()); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + result.AppendError ("invalid process"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + return result.Succeeded(); + } +}; + //------------------------------------------------------------------------- // CommandObjectProcessStatus //------------------------------------------------------------------------- @@ -1824,10 +1923,10 @@ protected: OptionDefinition CommandObjectProcessHandle::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_1, false, "stop", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." }, -{ LLDB_OPT_SET_1, false, "notify", 'n', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." }, -{ LLDB_OPT_SET_1, false, "pass", 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_1, false, "stop", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." }, +{ LLDB_OPT_SET_1, false, "notify", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." }, +{ LLDB_OPT_SET_1, false, "pass", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }, +{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -1853,6 +1952,7 @@ CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter))); LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter))); LoadSubCommand ("plugin", CommandObjectSP (new CommandObjectProcessPlugin (interpreter))); + LoadSubCommand ("save-core", CommandObjectSP (new CommandObjectProcessSaveCore (interpreter))); } CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess () diff --git a/source/Commands/CommandObjectQuit.cpp b/source/Commands/CommandObjectQuit.cpp index ffe2a9240726..dd0efc61b2d0 100644 --- a/source/Commands/CommandObjectQuit.cpp +++ b/source/Commands/CommandObjectQuit.cpp @@ -53,7 +53,7 @@ CommandObjectQuit::ShouldAskForConfirmation (bool& is_a_detach) continue; const TargetList& target_list(debugger_sp->GetTargetList()); for (uint32_t target_idx = 0; - target_idx < target_list.GetNumTargets(); + target_idx < static_cast(target_list.GetNumTargets()); target_idx++) { TargetSP target_sp(target_list.GetTargetAtIndex(target_idx)); diff --git a/source/Commands/CommandObjectRegister.cpp b/source/Commands/CommandObjectRegister.cpp index deaf2ab3793e..81b79b8cd8b2 100644 --- a/source/Commands/CommandObjectRegister.cpp +++ b/source/Commands/CommandObjectRegister.cpp @@ -31,6 +31,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Thread.h" +#include "llvm/ADT/STLExtras.h" using namespace lldb; using namespace lldb_private; @@ -202,7 +203,7 @@ protected: } else { - result.AppendErrorWithFormat ("invalid register set index: %zu\n", set_idx); + result.AppendErrorWithFormat("invalid register set index: %" PRIu64 "\n", (uint64_t)set_idx); result.SetStatus (eReturnStatusFailed); break; } @@ -352,15 +353,15 @@ protected: const OptionDefinition CommandObjectRegisterRead::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "alternate", 'A', OptionParser::eNoArgument , NULL, 0, eArgTypeNone , "Display register names using the alternate register name if there is one."}, - { LLDB_OPT_SET_1 , false, "set" , 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeIndex , "Specify which register sets to dump by index."}, - { LLDB_OPT_SET_2 , false, "all" , 'a', OptionParser::eNoArgument , NULL, 0, eArgTypeNone , "Show all register sets."}, + { LLDB_OPT_SET_ALL, false, "alternate", 'A', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone , "Display register names using the alternate register name if there is one."}, + { LLDB_OPT_SET_1 , false, "set" , 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeIndex , "Specify which register sets to dump by index."}, + { LLDB_OPT_SET_2 , false, "all" , 'a', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone , "Show all register sets."}, }; uint32_t CommandObjectRegisterRead::CommandOptions::GetNumDefinitions () { - return sizeof(g_option_table)/sizeof(OptionDefinition); + return llvm::array_lengthof(g_option_table); } diff --git a/source/Commands/CommandObjectSettings.cpp b/source/Commands/CommandObjectSettings.cpp index 78a5ad6ca86a..ed677afabcb5 100644 --- a/source/Commands/CommandObjectSettings.cpp +++ b/source/Commands/CommandObjectSettings.cpp @@ -164,7 +164,8 @@ insert-before or insert-after.\n"); const size_t argc = input.GetArgumentCount(); const char *arg = NULL; int setting_var_idx; - for (setting_var_idx = 1; setting_var_idx < argc; ++setting_var_idx) + for (setting_var_idx = 1; setting_var_idx < static_cast(argc); + ++setting_var_idx) { arg = input.GetArgumentAtIndex(setting_var_idx); if (arg && arg[0] != '-') @@ -288,8 +289,8 @@ private: OptionDefinition CommandObjectSettingsSet::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_2, false, "global", 'g', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Apply the new value to the global default value." }, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_2, false, "global", 'g', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Apply the new value to the global default value." }, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -1154,7 +1155,7 @@ protected: if (argc != 1) { - result.AppendError ("'setttings clear' takes exactly one argument"); + result.AppendError ("'settings clear' takes exactly one argument"); result.SetStatus (eReturnStatusFailed); return false; } diff --git a/source/Commands/CommandObjectSource.cpp b/source/Commands/CommandObjectSource.cpp index bf2a42e0bea0..6b1b6aacc857 100644 --- a/source/Commands/CommandObjectSource.cpp +++ b/source/Commands/CommandObjectSource.cpp @@ -138,9 +138,9 @@ protected: OptionDefinition CommandObjectSourceInfo::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum, "The line number at which to start the display source."}, -{ LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."}, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, "The line number at which to start the display source."}, +{ LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."}, +{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; #pragma mark CommandObjectSourceList @@ -804,7 +804,7 @@ protected: result.SetStatus (eReturnStatusFailed); return false; } - + if (num_matches > 1) { bool got_multiple = false; @@ -820,7 +820,7 @@ protected: { if (test_cu_spec != static_cast (sc.comp_unit)) got_multiple = true; - break; + break; } else test_cu_spec = sc.comp_unit; @@ -828,7 +828,7 @@ protected: } if (got_multiple) { - result.AppendErrorWithFormat("Multiple source files found matching: \"%s.\"\n", + result.AppendErrorWithFormat("Multiple source files found matching: \"%s.\"\n", m_options.file_name.c_str()); result.SetStatus (eReturnStatusFailed); return false; @@ -891,16 +891,16 @@ protected: OptionDefinition CommandObjectSourceList::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, "The number of source lines to display."}, +{ LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "The number of source lines to display."}, { LLDB_OPT_SET_1 | - LLDB_OPT_SET_2 , false, "shlib", 's', OptionParser::eRequiredArgument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library."}, -{ LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints."}, -{ LLDB_OPT_SET_1 , false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."}, -{ LLDB_OPT_SET_1 , false, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum, "The line number at which to start the display source."}, -{ LLDB_OPT_SET_2 , false, "name", 'n', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display."}, -{ LLDB_OPT_SET_3 , false, "address",'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line."}, -{ LLDB_OPT_SET_4, false, "reverse", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Reverse the listing to look backwards from the last displayed block of source."}, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + LLDB_OPT_SET_2 , false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library."}, +{ LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints."}, +{ LLDB_OPT_SET_1 , false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."}, +{ LLDB_OPT_SET_1 , false, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, "The line number at which to start the display source."}, +{ LLDB_OPT_SET_2 , false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display."}, +{ LLDB_OPT_SET_3 , false, "address",'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line."}, +{ LLDB_OPT_SET_4, false, "reverse", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Reverse the listing to look backwards from the last displayed block of source."}, +{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; #pragma mark CommandObjectMultiwordSource diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp index 308b72f355d3..024f7b5a0415 100644 --- a/source/Commands/CommandObjectTarget.cpp +++ b/source/Commands/CommandObjectTarget.cpp @@ -63,18 +63,18 @@ static void DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm) { const ArchSpec &target_arch = target->GetArchitecture(); - + Module *exe_module = target->GetExecutableModulePointer(); char exe_path[PATH_MAX]; bool exe_valid = false; if (exe_module) exe_valid = exe_module->GetFileSpec().GetPath (exe_path, sizeof(exe_path)); - + if (!exe_valid) ::strcpy (exe_path, ""); - + strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path); - + uint32_t properties = 0; if (target_arch.IsValid()) { @@ -84,7 +84,7 @@ DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bo PlatformSP platform_sp (target->GetPlatform()); if (platform_sp) strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName().GetCString()); - + ProcessSP process_sp (target->GetProcessSP()); bool show_process_status = false; if (process_sp) @@ -123,7 +123,7 @@ DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Strea { const uint32_t num_targets = target_list.GetNumTargets(); if (num_targets) - { + { TargetSP selected_target_sp (target_list.GetSelectedTarget()); strm.PutCString ("Current targets:\n"); for (uint32_t i=0; iGetExecutableSearchPaths ().Append (core_file_dir); - + ProcessSP process_sp (target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), NULL, &core_file)); if (process_sp) @@ -360,7 +386,7 @@ protected: // Seems wierd that we Launch a core file, but that is // what we do! error = process_sp->LoadCore(); - + if (error.Fail()) { result.AppendError(error.AsCString("can't find plug-in for core file")); @@ -403,7 +429,6 @@ protected: result.SetStatus (eReturnStatusFailed); } return result.Succeeded(); - } private: @@ -434,12 +459,12 @@ public: 0) { } - + virtual ~CommandObjectTargetList () { } - + protected: virtual bool DoExecute (Args& args, CommandReturnObject &result) @@ -447,7 +472,7 @@ protected: if (args.GetArgumentCount() == 0) { Stream &strm = result.GetOutputStream(); - + bool show_stopped_process_status = false; if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0) { @@ -482,12 +507,12 @@ public: 0) { } - + virtual ~CommandObjectTargetSelect () { } - + protected: virtual bool DoExecute (Args& args, CommandReturnObject &result) @@ -520,9 +545,16 @@ protected: } else { - result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n", - target_idx, - num_targets - 1); + if (num_targets > 0) + { + result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n", + target_idx, + num_targets - 1); + } else + { + result.AppendErrorWithFormat ("index %u is out of range since there are no active targets\n", + target_idx); + } result.SetStatus (eReturnStatusFailed); } } @@ -562,12 +594,12 @@ public: m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Finalize(); } - + virtual ~CommandObjectTargetDelete () { } - + Options * GetOptions () { @@ -600,7 +632,7 @@ protected: if (success) { if (target_idx < num_targets) - { + { target_sp = target_list.GetTargetAtIndex (target_idx); if (target_sp) { @@ -626,7 +658,6 @@ protected: success = false; } } - } else { @@ -661,10 +692,10 @@ protected: result.GetOutputStream().Printf("%u targets deleted.\n", (uint32_t)num_targets_to_delete); result.SetStatus(eReturnStatusSuccessFinishResult); } - + return result.Succeeded(); } - + OptionGroupOptions m_option_group; OptionGroupBoolean m_cleanup_option; }; @@ -678,6 +709,9 @@ protected: class CommandObjectTargetVariable : public CommandObjectParsed { + static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file' + static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb' + public: CommandObjectTargetVariable (CommandInterpreter &interpreter) : CommandObjectParsed (interpreter, @@ -688,23 +722,27 @@ public: m_option_group (interpreter), m_option_variable (false), // Don't include frame options m_option_format (eFormatDefault), - m_option_compile_units (LLDB_OPT_SET_1, false, "file", 'file', 0, eArgTypeFilename, "A basename or fullpath to a file that contains global variables. This option can be specified multiple times."), - m_option_shared_libraries (LLDB_OPT_SET_1, false, "shlib",'shlb', 0, eArgTypeFilename, "A basename or fullpath to a shared library to use in the search for global variables. This option can be specified multiple times."), + m_option_compile_units (LLDB_OPT_SET_1, false, "file", + SHORT_OPTION_FILE, 0, eArgTypeFilename, + "A basename or fullpath to a file that contains global variables. This option can be specified multiple times."), + m_option_shared_libraries (LLDB_OPT_SET_1, false, "shlib", + SHORT_OPTION_SHLB, 0, eArgTypeFilename, + "A basename or fullpath to a shared library to use in the search for global variables. This option can be specified multiple times."), m_varobj_options() { CommandArgumentEntry arg; CommandArgumentData var_name_arg; - + // Define the first (and only) variant of this arg. var_name_arg.arg_type = eArgTypeVarName; var_name_arg.arg_repetition = eArgRepeatPlus; - + // There is only one variant this argument could be; put it into the argument entry. arg.push_back (var_name_arg); - + // Push the data for the first argument into the m_arguments vector. m_arguments.push_back (arg); - + m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Append (&m_option_format, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1); @@ -712,7 +750,7 @@ public: m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Finalize(); } - + virtual ~CommandObjectTargetVariable () { @@ -722,33 +760,33 @@ public: DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name) { DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions()); - + switch (var_sp->GetScope()) { case eValueTypeVariableGlobal: if (m_option_variable.show_scope) s.PutCString("GLOBAL: "); break; - + case eValueTypeVariableStatic: if (m_option_variable.show_scope) s.PutCString("STATIC: "); break; - + case eValueTypeVariableArgument: if (m_option_variable.show_scope) s.PutCString(" ARG: "); break; - + case eValueTypeVariableLocal: if (m_option_variable.show_scope) s.PutCString(" LOCAL: "); break; - + default: break; } - + if (m_option_variable.show_decl) { bool show_fullpaths = false; @@ -756,17 +794,16 @@ public: if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module)) s.PutCString (": "); } - + const Format format = m_option_format.GetFormat(); if (format != eFormatDefault) options.SetFormat(format); options.SetRootValueObjectName(root_name); - + valobj_sp->Dump(s,options); } - - + static size_t GetVariableCallback (void *baton, const char *name, VariableList &variable_list) @@ -781,17 +818,14 @@ public: } return 0; } - - Options * GetOptions () { return &m_option_group; } - + protected: - void DumpGlobalVariableList(const ExecutionContext &exe_ctx, const SymbolContext &sc, const VariableList &variable_list, Stream &s) { @@ -817,14 +851,14 @@ protected: s.Printf ("Global variables for %s\n", sc.comp_unit->GetPath().c_str()); } - + for (uint32_t i=0; iGetName().GetCString()); } @@ -838,7 +872,7 @@ protected: Target *target = m_exe_ctx.GetTargetPtr(); const size_t argc = args.GetArgumentCount(); Stream &s = result.GetOutputStream(); - + if (argc > 0) { @@ -875,7 +909,7 @@ protected: valobj_list)); matches = variable_list.GetSize(); } - + if (matches == 0) { result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg); @@ -892,7 +926,7 @@ protected: ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx)); if (!valobj_sp) valobj_sp = ValueObjectVariable::Create (m_exe_ctx.GetBestExecutionContextScope(), var_sp); - + if (valobj_sp) DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg); } @@ -939,7 +973,7 @@ protected: comp_unit->GetPath().c_str()); else result.AppendErrorWithFormat ("no debug information for frame %u\n", frame->GetFrameIndex()); - } + } else result.AppendError ("'target variable' takes one or more global variable names as arguments\n"); result.SetStatus (eReturnStatusFailed); @@ -956,7 +990,7 @@ protected: { const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx)); ModuleSpec module_spec (module_file); - + ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec)); if (module_sp) { @@ -986,7 +1020,7 @@ protected: for (size_t cu_idx=0; cu_idxGetImages().FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list); } - + const uint32_t num_scs = sc_list.GetSize(); if (num_scs > 0) { @@ -1022,10 +1056,10 @@ protected: m_cmd_name.c_str()); m_interpreter.TruncationWarningGiven(); } - + return result.Succeeded(); } - + OptionGroupOptions m_option_group; OptionGroupVariable m_option_variable; OptionGroupFormat m_option_format; @@ -1051,15 +1085,15 @@ public: CommandArgumentEntry arg; CommandArgumentData old_prefix_arg; CommandArgumentData new_prefix_arg; - + // Define the first variant of this arg pair. old_prefix_arg.arg_type = eArgTypeOldPathPrefix; old_prefix_arg.arg_repetition = eArgRepeatPairPlus; - + // Define the first variant of this arg pair. new_prefix_arg.arg_type = eArgTypeNewPathPrefix; new_prefix_arg.arg_repetition = eArgRepeatPairPlus; - + // There are two required arguments that must always occur together, i.e. an argument "pair". Because they // must always occur together, they are treated as two variants of one argument rather than two independent // arguments. Push them both into the first argument position for m_arguments... @@ -1094,7 +1128,7 @@ protected: { const char *from = command.GetArgumentAtIndex(i); const char *to = command.GetArgumentAtIndex(i+1); - + if (from[0] && to[0]) { bool last_pair = ((argc - i) == 2); @@ -1179,7 +1213,7 @@ public: CommandArgumentData index_arg; CommandArgumentData old_prefix_arg; CommandArgumentData new_prefix_arg; - + // Define the first and only variant of this arg. index_arg.arg_type = eArgTypeIndex; index_arg.arg_repetition = eArgRepeatPlain; @@ -1190,11 +1224,11 @@ public: // Define the first variant of this arg pair. old_prefix_arg.arg_type = eArgTypeOldPathPrefix; old_prefix_arg.arg_repetition = eArgRepeatPairPlus; - + // Define the first variant of this arg pair. new_prefix_arg.arg_type = eArgTypeNewPathPrefix; new_prefix_arg.arg_repetition = eArgRepeatPairPlus; - + // There are two required arguments that must always occur together, i.e. an argument "pair". Because they // must always occur together, they are treated as two variants of one argument rather than two independent // arguments. Push them both into the same argument position for m_arguments... @@ -1242,7 +1276,7 @@ protected: { const char *from = command.GetArgumentAtIndex(i); const char *to = command.GetArgumentAtIndex(i+1); - + if (from[0] && to[0]) { bool last_pair = ((argc - i) == 2); @@ -1341,14 +1375,14 @@ public: { CommandArgumentEntry arg; CommandArgumentData path_arg; - + // Define the first (and only) variant of this arg. path_arg.arg_type = eArgTypeDirectoryName; path_arg.arg_repetition = eArgRepeatPlain; - + // There is only one variant this argument could be; put it into the argument entry. arg.push_back (path_arg); - + // Push the data for the first argument into the m_arguments vector. m_arguments.push_back (arg); } @@ -1435,7 +1469,7 @@ DumpCompileUnitLineTable (CommandInterpreter &interpreter, false, eSymbolContextCompUnit, sc_list); - + for (uint32_t i=0; i 0) strm << "\n\n"; - + strm << "Line table for " << *static_cast (sc.comp_unit) << " in `" << module->GetFileSpec().GetFilename() << "\n"; LineTable *line_table = sc.comp_unit->GetLineTable(); @@ -1612,7 +1646,7 @@ LookupAddressInModule (CommandInterpreter &interpreter, if (!module->ResolveFileAddress (addr, so_addr)) return false; } - + ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope(); DumpAddress (exe_scope, so_addr, verbose, strm); // strm.IndentMore(); @@ -1635,7 +1669,7 @@ LookupAddressInModule (CommandInterpreter &interpreter, // strm.IndentLess(); return true; } - + return false; } @@ -1645,7 +1679,7 @@ LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *mod if (module) { SymbolContext sc; - + SymbolVendor *sym_vendor = module->GetSymbolVendor (); if (sym_vendor) { @@ -1667,8 +1701,7 @@ LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *mod { num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes); } - - + if (num_matches > 0) { strm.Indent (); @@ -1705,19 +1738,19 @@ DumpSymbolContextList (ExecutionContextScope *exe_scope, Stream &strm, SymbolCon strm.IndentMore (); uint32_t i; const uint32_t num_matches = sc_list.GetSize(); - + for (i=0; i 1 ? "es" : ""); + strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, num_matches > 1 ? "es" : ""); DumpFullpath (strm, &module->GetFileSpec(), 0); strm.PutCString(":\n"); DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose); @@ -1790,11 +1823,11 @@ LookupTypeInModule (CommandInterpreter &interpreter, ConstString name(name_cstr); num_matches = module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches, type_list); - + if (num_matches) { strm.Indent (); - strm.Printf("%zu match%s found in ", num_matches, num_matches > 1 ? "es" : ""); + strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, num_matches > 1 ? "es" : ""); DumpFullpath (strm, &module->GetFileSpec(), 0); strm.PutCString(":\n"); for (TypeSP type_sp : type_list.Types()) @@ -1835,22 +1868,22 @@ LookupTypeHere (CommandInterpreter &interpreter, { if (!sym_ctx.module_sp) return 0; - + TypeList type_list; const uint32_t max_num_matches = UINT32_MAX; size_t num_matches = 1; bool name_is_fully_qualified = false; - + ConstString name(name_cstr); num_matches = sym_ctx.module_sp->FindTypes(sym_ctx, name, name_is_fully_qualified, max_num_matches, type_list); - + if (num_matches) { strm.Indent (); strm.PutCString("Best match found in "); DumpFullpath (strm, &sym_ctx.module_sp->GetFileSpec(), 0); strm.PutCString(":\n"); - + TypeSP type_sp (type_list.GetTypeAtIndex(0)); if (type_sp) { @@ -1905,7 +1938,6 @@ LookupFileAndLineInModule (CommandInterpreter &interpreter, } } return 0; - } @@ -1918,7 +1950,7 @@ FindModulesByName (Target *target, // Dump specified images (by basename or fullpath) FileSpec module_file_spec(module_name, false); ModuleSpec module_spec (module_file_spec); - + const size_t initial_size = module_list.GetSize (); if (check_global_list) @@ -1930,7 +1962,7 @@ FindModulesByName (Target *target, for (size_t image_idx = 0; image_idxMatchesModuleSpec (module_spec)) @@ -1946,7 +1978,7 @@ FindModulesByName (Target *target, if (target) { const size_t num_matches = target->GetImages().FindModules (module_spec, module_list); - + // Not found in our module list for our target, check the main // shared module list in case it is a extra file used somewhere // else @@ -1961,7 +1993,7 @@ FindModulesByName (Target *target, ModuleList::FindSharedModules (module_spec,module_list); } } - + return module_list.GetSize () - initial_size; } @@ -1975,7 +2007,6 @@ FindModulesByName (Target *target, class CommandObjectTargetModulesModuleAutoComplete : public CommandObjectParsed { public: - CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter, const char *name, const char *help, @@ -1984,23 +2015,23 @@ public: { CommandArgumentEntry arg; CommandArgumentData file_arg; - + // Define the first (and only) variant of this arg. file_arg.arg_type = eArgTypeFilename; file_arg.arg_repetition = eArgRepeatStar; - + // There is only one variant this argument could be; put it into the argument entry. arg.push_back (file_arg); - + // Push the data for the first argument into the m_arguments vector. m_arguments.push_back (arg); } - + virtual ~CommandObjectTargetModulesModuleAutoComplete () { } - + virtual int HandleArgumentCompletion (Args &input, int &cursor_index, @@ -2014,7 +2045,7 @@ public: // Arguments are the standard module completer. std::string completion_str (input.GetArgumentAtIndex(cursor_index)); completion_str.erase (cursor_char_position); - + CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, CommandCompletions::eModuleCompletion, completion_str.c_str(), @@ -2037,7 +2068,6 @@ public: class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObjectParsed { public: - CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter, const char *name, const char *help, @@ -2047,23 +2077,23 @@ public: { CommandArgumentEntry arg; CommandArgumentData source_file_arg; - + // Define the first (and only) variant of this arg. source_file_arg.arg_type = eArgTypeSourceFile; source_file_arg.arg_repetition = eArgRepeatPlus; - + // There is only one variant this argument could be; put it into the argument entry. arg.push_back (source_file_arg); - + // Push the data for the first argument into the m_arguments vector. m_arguments.push_back (arg); } - + virtual ~CommandObjectTargetModulesSourceFileAutoComplete () { } - + virtual int HandleArgumentCompletion (Args &input, int &cursor_index, @@ -2077,7 +2107,7 @@ public: // Arguments are the standard source file completer. std::string completion_str (input.GetArgumentAtIndex(cursor_index)); completion_str.erase (cursor_char_position); - + CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, CommandCompletions::eSourceFileCompletion, completion_str.c_str(), @@ -2105,39 +2135,38 @@ public: m_options (interpreter) { } - + virtual ~CommandObjectTargetModulesDumpSymtab () { } - + virtual Options * GetOptions () { return &m_options; } - + class CommandOptions : public Options { public: - CommandOptions (CommandInterpreter &interpreter) : Options(interpreter), m_sort_order (eSortOrderNone) { } - + virtual ~CommandOptions () { } - + virtual Error SetOptionValue (uint32_t option_idx, const char *option_arg) { Error error; const int short_option = m_getopt_table[option_idx].val; - + switch (short_option) { case 's': @@ -2146,33 +2175,33 @@ public: eSortOrderNone, error); break; - + default: error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); break; - + } return error; } - + void OptionParsingStarting () { m_sort_order = eSortOrderNone; } - + const OptionDefinition* GetDefinitions () { return g_option_table; } - + // Options table: Required for subclasses of Options. static OptionDefinition g_option_table[]; - + SortOrder m_sort_order; }; - + protected: virtual bool DoExecute (Args& command, @@ -2188,11 +2217,11 @@ protected: else { uint32_t num_dumped = 0; - + uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); result.GetOutputStream().SetAddressByteSize(addr_byte_size); result.GetErrorStream().SetAddressByteSize(addr_byte_size); - + if (command.GetArgumentCount() == 0) { // Dump all sections for all modules images @@ -2200,7 +2229,7 @@ protected: const size_t num_modules = target->GetImages().GetSize(); if (num_modules > 0) { - result.GetOutputStream().Printf("Dumping symbol table for %zu modules.\n", num_modules); + result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64 " modules.\n", (uint64_t)num_modules); for (size_t image_idx = 0; image_idx 0) @@ -2251,7 +2280,7 @@ protected: result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); } } - + if (num_dumped > 0) result.SetStatus (eReturnStatusSuccessFinishResult); else @@ -2262,8 +2291,7 @@ protected: } return result.Succeeded(); } - - + CommandOptions m_options; }; @@ -2280,8 +2308,8 @@ g_sort_option_enumeration[4] = OptionDefinition CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, NULL, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; #pragma mark CommandObjectTargetModulesDumpSections @@ -2301,12 +2329,12 @@ public: NULL) { } - + virtual ~CommandObjectTargetModulesDumpSections () { } - + protected: virtual bool DoExecute (Args& command, @@ -2322,18 +2350,18 @@ protected: else { uint32_t num_dumped = 0; - + uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); result.GetOutputStream().SetAddressByteSize(addr_byte_size); result.GetErrorStream().SetAddressByteSize(addr_byte_size); - + if (command.GetArgumentCount() == 0) { // Dump all sections for all modules images const size_t num_modules = target->GetImages().GetSize(); if (num_modules > 0) { - result.GetOutputStream().Printf("Dumping sections for %zu modules.\n", num_modules); + result.GetOutputStream().Printf("Dumping sections for %" PRIu64 " modules.\n", (uint64_t)num_modules); for (size_t image_idx = 0; image_idx 0) result.SetStatus (eReturnStatusSuccessFinishResult); else @@ -2407,12 +2435,12 @@ public: NULL) { } - + virtual ~CommandObjectTargetModulesDumpSymfile () { } - + protected: virtual bool DoExecute (Args& command, @@ -2428,11 +2456,11 @@ protected: else { uint32_t num_dumped = 0; - + uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); result.GetOutputStream().SetAddressByteSize(addr_byte_size); result.GetErrorStream().SetAddressByteSize(addr_byte_size); - + if (command.GetArgumentCount() == 0) { // Dump all sections for all modules images @@ -2441,7 +2469,7 @@ protected: const size_t num_modules = target_modules.GetSize(); if (num_modules > 0) { - result.GetOutputStream().Printf("Dumping debug symbols for %zu modules.\n", num_modules); + result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64 " modules.\n", (uint64_t)num_modules); for (uint32_t image_idx = 0; image_idx 0) result.SetStatus (eReturnStatusSuccessFinishResult); else @@ -2510,12 +2538,12 @@ public: eFlagRequiresTarget) { } - + virtual ~CommandObjectTargetModulesDumpLineTable () { } - + protected: virtual bool DoExecute (Args& command, @@ -2523,11 +2551,11 @@ protected: { Target *target = m_exe_ctx.GetTargetPtr(); uint32_t total_num_dumped = 0; - + uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); result.GetOutputStream().SetAddressByteSize(addr_byte_size); result.GetErrorStream().SetAddressByteSize(addr_byte_size); - + if (command.GetArgumentCount() == 0) { result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str()); @@ -2540,7 +2568,7 @@ protected: for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) { FileSpec file_spec(arg_cstr, false); - + const ModuleList &target_modules = target->GetImages(); Mutex::Locker modules_locker(target_modules.GetMutex()); const size_t num_modules = target_modules.GetSize(); @@ -2563,7 +2591,7 @@ protected: } } } - + if (total_num_dumped > 0) result.SetStatus (eReturnStatusSuccessFinishResult); else @@ -2585,7 +2613,6 @@ protected: class CommandObjectTargetModulesDump : public CommandObjectMultiword { public: - //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ @@ -2600,7 +2627,7 @@ public: LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter))); LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter))); } - + virtual ~CommandObjectTargetModulesDump() { @@ -2622,18 +2649,18 @@ public: m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Finalize(); } - + virtual ~CommandObjectTargetModulesAdd () { } - + virtual Options * GetOptions () { return &m_option_group; } - + virtual int HandleArgumentCompletion (Args &input, int &cursor_index, @@ -2646,7 +2673,7 @@ public: { std::string completion_str (input.GetArgumentAtIndex(cursor_index)); completion_str.erase (cursor_char_position); - + CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, CommandCompletions::eDiskFileCompletion, completion_str.c_str(), @@ -2659,11 +2686,9 @@ public: } protected: - OptionGroupOptions m_option_group; OptionGroupUUID m_uuid_option_group; OptionGroupFile m_symbol_file; - virtual bool DoExecute (Args& args, @@ -2679,7 +2704,7 @@ protected: else { bool flush = false; - + const size_t argc = args.GetArgumentCount(); if (argc == 0) { @@ -2700,8 +2725,6 @@ protected: } else { - flush = true; - StreamString strm; module_spec.GetUUID().Dump (&strm); if (module_spec.GetFileSpec()) @@ -2798,7 +2821,7 @@ protected: } } } - + if (flush) { ProcessSP process = target->GetProcessSP(); @@ -2806,7 +2829,7 @@ protected: process->Flush(); } } - + return result.Succeeded(); } @@ -2829,18 +2852,18 @@ public: m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Finalize(); } - + virtual ~CommandObjectTargetModulesLoad () { } - + virtual Options * GetOptions () { return &m_option_group; } - + protected: virtual bool DoExecute (Args& args, @@ -2863,7 +2886,7 @@ protected: search_using_module_spec = true; module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); } - + if (m_uuid_option_group.GetOptionValue().OptionWasSet()) { search_using_module_spec = true; @@ -2872,7 +2895,6 @@ protected: if (search_using_module_spec) { - ModuleList matching_modules; const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules); @@ -2965,7 +2987,7 @@ protected: } } } - + if (changed) { target->ModulesDidLoad (matching_modules); @@ -3004,7 +3026,7 @@ protected: else { std::string uuid_str; - + if (module_spec.GetFileSpec()) module_spec.GetFileSpec().GetPath (path, sizeof(path)); else @@ -3044,8 +3066,8 @@ protected: } } return result.Succeeded(); - } - + } + OptionGroupOptions m_option_group; OptionGroupUUID m_uuid_option_group; OptionGroupFile m_file_option; @@ -3058,11 +3080,9 @@ protected: class CommandObjectTargetModulesList : public CommandObjectParsed { public: - class CommandOptions : public Options { public: - CommandOptions (CommandInterpreter &interpreter) : Options(interpreter), m_format_array(), @@ -3070,12 +3090,12 @@ public: m_module_addr (LLDB_INVALID_ADDRESS) { } - + virtual ~CommandOptions () { } - + virtual Error SetOptionValue (uint32_t option_idx, const char *option_arg) { @@ -3100,7 +3120,7 @@ public: } return error; } - + void OptionParsingStarting () { @@ -3108,24 +3128,24 @@ public: m_use_global_module_list = false; m_module_addr = LLDB_INVALID_ADDRESS; } - + const OptionDefinition* GetDefinitions () { return g_option_table; } - + // Options table: Required for subclasses of Options. - + static OptionDefinition g_option_table[]; - + // Instance variables to hold the values for command options. typedef std::vector< std::pair > FormatWidthCollection; FormatWidthCollection m_format_array; bool m_use_global_module_list; lldb::addr_t m_module_addr; }; - + CommandObjectTargetModulesList (CommandInterpreter &interpreter) : CommandObjectParsed (interpreter, "target modules list", @@ -3134,19 +3154,19 @@ public: m_options (interpreter) { } - + virtual ~CommandObjectTargetModulesList () { } - + virtual Options * GetOptions () { return &m_options; } - + protected: virtual bool DoExecute (Args& command, @@ -3174,7 +3194,7 @@ protected: } // Dump all sections for all modules images Stream &strm = result.GetOutputStream(); - + if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) { if (target) @@ -3207,7 +3227,7 @@ protected: } return result.Succeeded(); } - + size_t num_modules = 0; Mutex::Locker locker; // This locker will be locked on the mutex in module_list_ptr if it is non-NULL. // Otherwise it will lock the AllocationModuleCollectionMutex when accessing @@ -3243,10 +3263,10 @@ protected: } } } - + module_list_ptr = &module_list; } - + if (module_list_ptr != NULL) { locker.Lock(module_list_ptr->GetMutex()); @@ -3254,7 +3274,7 @@ protected: } if (num_modules > 0) - { + { for (uint32_t image_idx = 0; image_idxshared_from_this(); } - + const size_t indent = strm.Printf("[%3u] ", image_idx); PrintModule (target, module, indent, strm); @@ -3308,7 +3328,7 @@ protected: strm.PutCString("Null module"); return; } - + bool dump_object_name = false; if (m_options.m_format_array.empty()) { @@ -3331,25 +3351,25 @@ protected: case 'A': DumpModuleArchitecture (strm, module, false, width); break; - + case 't': DumpModuleArchitecture (strm, module, true, width); break; - + case 'f': DumpFullpath (strm, &module->GetFileSpec(), width); dump_object_name = true; break; - + case 'd': DumpDirectory (strm, &module->GetFileSpec(), width); break; - + case 'b': DumpBasename (strm, &module->GetFileSpec(), width); dump_object_name = true; break; - + case 'h': case 'o': // Image header address @@ -3402,9 +3422,9 @@ protected: ref_count = module_sp.use_count() - 1; } if (width) - strm.Printf("{%*zu}", width, ref_count); + strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count); else - strm.Printf("{%zu}", ref_count); + strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count); } break; @@ -3437,23 +3457,23 @@ protected: strm.Printf("%.*s", width, ""); } break; - + case 'm': module->GetModificationTime().Dump(&strm, width); break; case 'p': - strm.Printf("%p", module); + strm.Printf("%p", static_cast(module)); break; case 'u': DumpModuleUUID(strm, module); break; - + default: break; } - + } if (dump_object_name) { @@ -3463,29 +3483,29 @@ protected: } strm.EOL(); } - + CommandOptions m_options; }; OptionDefinition CommandObjectTargetModulesList::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression, "Display the image at this address."}, - { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, - { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, - { LLDB_OPT_SET_1, false, "header", 'h', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise."}, - { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Display the image header address offset from the header file address (the slide amount)."}, - { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, - { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, - { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, - { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."}, - { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."}, - { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, NULL, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file."}, - { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."}, - { LLDB_OPT_SET_1, false, "ref-count", 'r', OptionParser::eOptionalArgument, NULL, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache."}, - { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, NULL, 0, eArgTypeNone, "Display the module pointer."}, - { LLDB_OPT_SET_1, false, "global", 'g', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Display the image at this address."}, + { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, + { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, + { LLDB_OPT_SET_1, false, "header", 'h', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise."}, + { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the image header address offset from the header file address (the slide amount)."}, + { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, + { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, + { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, + { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."}, + { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."}, + { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file."}, + { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."}, + { LLDB_OPT_SET_1, false, "ref-count", 'r', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache."}, + { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeNone, "Display the module pointer."}, + { LLDB_OPT_SET_1, false, "global", 'g', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; #pragma mark CommandObjectTargetModulesShowUnwind @@ -3584,7 +3604,7 @@ public: std::string m_str; // Holds name lookup lldb::addr_t m_addr; // Holds the address to lookup }; - + CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) : CommandObjectParsed (interpreter, "target modules show-unwind", @@ -3597,12 +3617,12 @@ public: m_options (interpreter) { } - + virtual ~CommandObjectTargetModulesShowUnwind () { } - + virtual Options * GetOptions () @@ -3645,7 +3665,7 @@ protected: } SymbolContextList sc_list; - + if (m_options.m_type == eLookupTypeFunctionOrSymbol) { ConstString function_name (m_options.m_str.c_str()); @@ -3711,7 +3731,7 @@ protected: result.GetOutputStream().Printf ("\n"); } - UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*thread.get()); + UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread.get(), -1); if (non_callsite_unwind_plan.get()) { result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); @@ -3755,9 +3775,9 @@ protected: OptionDefinition CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."}, - { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."}, + { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //---------------------------------------------------------------------- @@ -3766,7 +3786,6 @@ CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] = class CommandObjectTargetModulesLookup : public CommandObjectParsed { public: - enum { eLookupTypeInvalid = -1, @@ -3778,29 +3797,28 @@ public: eLookupTypeType, kNumLookupTypes }; - + class CommandOptions : public Options { public: - CommandOptions (CommandInterpreter &interpreter) : Options(interpreter) { OptionParsingStarting(); } - + virtual ~CommandOptions () { } - + virtual Error SetOptionValue (uint32_t option_idx, const char *option_arg) { Error error; - + const int short_option = m_getopt_table[option_idx].val; - + switch (short_option) { case 'a': @@ -3810,27 +3828,27 @@ public: m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); } break; - + case 'o': m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); if (m_offset == LLDB_INVALID_ADDRESS) error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg); break; - + case 's': m_str = option_arg; m_type = eLookupTypeSymbol; break; - + case 'f': m_file.SetFile (option_arg, false); m_type = eLookupTypeFileLine; break; - + case 'i': m_include_inlines = false; break; - + case 'l': m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX); if (m_line_number == UINT32_MAX) @@ -3839,12 +3857,12 @@ public: error.SetErrorString ("zero is an invalid line number"); m_type = eLookupTypeFileLine; break; - + case 'F': m_str = option_arg; m_type = eLookupTypeFunction; break; - + case 'n': m_str = option_arg; m_type = eLookupTypeFunctionOrSymbol; @@ -3854,23 +3872,23 @@ public: m_str = option_arg; m_type = eLookupTypeType; break; - + case 'v': m_verbose = 1; break; - + case 'A': m_print_all = true; break; - + case 'r': m_use_regex = true; break; } - + return error; } - + void OptionParsingStarting () { @@ -3885,15 +3903,15 @@ public: m_verbose = false; m_print_all = false; } - + const OptionDefinition* GetDefinitions () { return g_option_table; } - + // Options table: Required for subclasses of Options. - + static OptionDefinition g_option_table[]; int m_type; // Should be a eLookupTypeXXX enum after parsing options std::string m_str; // Holds name lookup @@ -3905,9 +3923,8 @@ public: bool m_include_inlines;// Check for inline entries when looking up by file/line. bool m_verbose; // Enable verbose lookup info bool m_print_all; // Print all matches, even in cases where there's a best match. - }; - + CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) : CommandObjectParsed (interpreter, "target modules lookup", @@ -3918,29 +3935,29 @@ public: { CommandArgumentEntry arg; CommandArgumentData file_arg; - + // Define the first (and only) variant of this arg. file_arg.arg_type = eArgTypeFilename; file_arg.arg_repetition = eArgRepeatStar; - + // There is only one variant this argument could be; put it into the argument entry. arg.push_back (file_arg); - + // Push the data for the first argument into the m_arguments vector. m_arguments.push_back (arg); } - + virtual ~CommandObjectTargetModulesLookup () { } - + virtual Options * GetOptions () { return &m_options; } - + bool LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error) { @@ -3956,17 +3973,17 @@ public: case eLookupTypeType: break; } - + StackFrameSP frame = m_exe_ctx.GetFrameSP(); - + if (!frame) return false; - + const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule)); - + if (!sym_ctx.module_sp) return false; - + switch (m_options.m_type) { default: @@ -3986,10 +4003,10 @@ public: } break; } - + return true; } - + bool LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error) { @@ -4011,7 +4028,7 @@ public: } } break; - + case eLookupTypeSymbol: if (!m_options.m_str.empty()) { @@ -4027,11 +4044,10 @@ public: } } break; - + case eLookupTypeFileLine: if (m_options.m_file) { - if (LookupFileAndLineInModule (m_interpreter, result.GetOutputStream(), module, @@ -4064,8 +4080,7 @@ public: } } break; - - + case eLookupTypeType: if (!m_options.m_str.empty()) { @@ -4080,17 +4095,17 @@ public: } } break; - + default: m_options.GenerateOptionUsage (result.GetErrorStream(), this); syntax_error = true; break; } - + result.SetStatus (eReturnStatusFailed); return false; } - + protected: virtual bool DoExecute (Args& command, @@ -4112,11 +4127,11 @@ protected: result.GetOutputStream().SetAddressByteSize(addr_byte_size); result.GetErrorStream().SetAddressByteSize(addr_byte_size); // Dump all sections for all modules images - + if (command.GetArgumentCount() == 0) { ModuleSP current_module; - + // Where it is possible to look in the current symbol context // first, try that. If this search was successful and --all // was not passed, don't print anything else. @@ -4130,9 +4145,9 @@ protected: return result.Succeeded(); } } - + // Dump all sections for all other modules - + const ModuleList &target_modules = target->GetImages(); Mutex::Locker modules_locker(target_modules.GetMutex()); const size_t num_modules = target_modules.GetSize(); @@ -4141,7 +4156,7 @@ protected: for (i = 0; i 0) result.SetStatus (eReturnStatusSuccessFinishResult); else @@ -4192,29 +4207,29 @@ protected: } return result.Succeeded(); } - + CommandOptions m_options; }; OptionDefinition CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."}, - { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOffset, "When looking up an address subtract from any addresses before doing the lookup."}, + { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."}, + { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset, "When looking up an address subtract from any addresses before doing the lookup."}, { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ , - false, "regex", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "The argument for name lookups are regular expressions."}, - { LLDB_OPT_SET_2, true, "symbol", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules."}, - { LLDB_OPT_SET_3, true, "file", 'f', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules."}, - { LLDB_OPT_SET_3, false, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)."}, + false, "regex", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "The argument for name lookups are regular expressions."}, + { LLDB_OPT_SET_2, true, "symbol", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules."}, + { LLDB_OPT_SET_3, true, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules."}, + { LLDB_OPT_SET_3, false, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)."}, { LLDB_OPT_SET_FROM_TO(3,5), - false, "no-inlines", 'i', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."}, - { LLDB_OPT_SET_4, true, "function", 'F', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules."}, - { LLDB_OPT_SET_5, true, "name", 'n', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules."}, - { LLDB_OPT_SET_6, true, "type", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules."}, - { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."}, - { LLDB_OPT_SET_ALL, false, "all", 'A', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + false, "no-inlines", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."}, + { LLDB_OPT_SET_4, true, "function", 'F', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules."}, + { LLDB_OPT_SET_5, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules."}, + { LLDB_OPT_SET_6, true, "type", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules."}, + { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable verbose lookup information."}, + { LLDB_OPT_SET_ALL, false, "all", 'A', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -4227,7 +4242,6 @@ CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] = class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword { public: - CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) : CommandObjectMultiword (interpreter, "target modules search-paths", @@ -4240,7 +4254,7 @@ public: LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter))); LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter))); } - + ~CommandObjectTargetModulesImageSearchPaths() { } @@ -4279,7 +4293,7 @@ public: ~CommandObjectTargetModules() { } - + private: //------------------------------------------------------------------ // For CommandObjectTargetModules only @@ -4307,12 +4321,12 @@ public: m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2); m_option_group.Finalize(); } - + virtual ~CommandObjectTargetSymbolsAdd () { } - + virtual int HandleArgumentCompletion (Args &input, int &cursor_index, @@ -4325,7 +4339,7 @@ public: { std::string completion_str (input.GetArgumentAtIndex(cursor_index)); completion_str.erase (cursor_char_position); - + CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, CommandCompletions::eDiskFileCompletion, completion_str.c_str(), @@ -4336,16 +4350,14 @@ public: matches); return matches.GetSize(); } - + virtual Options * GetOptions () { return &m_option_group; } - protected: - bool AddModuleSymbols (Target *target, ModuleSpec &module_spec, @@ -4357,7 +4369,7 @@ protected: { char symfile_path[PATH_MAX]; symbol_fspec.GetPath (symfile_path, sizeof(symfile_path)); - + if (!module_spec.GetUUID().IsValid()) { if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec()) @@ -4368,7 +4380,7 @@ protected: // current target, so we need to find that module in the // target ModuleList matching_module_list; - + size_t num_matches = 0; // First extract all module specs from the symbol file lldb_private::ModuleSpecList symfile_module_specs; @@ -4389,7 +4401,7 @@ protected: num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list); } } - + if (num_matches == 0) { // No matches yet, iterate through the module specs to find a UUID value that @@ -4405,7 +4417,7 @@ protected: ModuleSpec symfile_uuid_module_spec; symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list); - } + } } } } @@ -4414,23 +4426,22 @@ protected: // Just try to match up the file by basename if we have no matches at this point if (num_matches == 0) num_matches = target->GetImages().FindModules (module_spec, matching_module_list); - + while (num_matches == 0) { ConstString filename_no_extension(module_spec.GetFileSpec().GetFileNameStrippingExtension()); // Empty string returned, lets bail if (!filename_no_extension) break; - + // Check if there was no extension to strip and the basename is the same if (filename_no_extension == module_spec.GetFileSpec().GetFilename()) break; - + // Replace basename with one less extension module_spec.GetFileSpec().GetFilename() = filename_no_extension; - + num_matches = target->GetImages().FindModules (module_spec, matching_module_list); - } if (num_matches > 1) @@ -4440,21 +4451,21 @@ protected: else if (num_matches == 1) { ModuleSP module_sp (matching_module_list.GetModuleAtIndex(0)); - + // The module has not yet created its symbol vendor, we can just // give the existing target module the symfile path to use for // when it decides to create it! module_sp->SetSymbolFileFileSpec (symbol_fspec); - + SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(true, &result.GetErrorStream()); if (symbol_vendor) { SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); - + if (symbol_file) { ObjectFile *object_file = symbol_file->GetObjectFile(); - + if (object_file && object_file->GetFileSpec() == symbol_fspec) { // Provide feedback that the symfile has been successfully added. @@ -4462,13 +4473,13 @@ protected: result.AppendMessageWithFormat("symbol file '%s' has been added to '%s'\n", symfile_path, module_fs.GetPath().c_str()); - + // Let clients know something changed in the module // if it is currently loaded ModuleList module_list; module_list.Append (module_sp); target->SymbolsDidLoad (module_list); - + // Make sure we load any scripting resources that may be embedded // in the debug info files in case the platform supports that. Error error; @@ -4674,7 +4685,7 @@ protected: if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success()) module_spec.GetSymbolFileSpec() = symfile_spec; } - + ArchSpec arch; bool symfile_exists = module_spec.GetSymbolFileSpec().Exists(); @@ -4710,13 +4721,11 @@ protected: } return result.Succeeded(); } - + OptionGroupOptions m_option_group; OptionGroupUUID m_uuid_option_group; OptionGroupFile m_file_option; OptionGroupBoolean m_current_frame_option; - - }; @@ -4739,13 +4748,13 @@ public: "target symbols ...") { LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter))); - + } virtual ~CommandObjectTargetSymbols() { } - + private: //------------------------------------------------------------------ // For CommandObjectTargetModules only @@ -4780,9 +4789,9 @@ public: m_one_liner() { } - + ~CommandOptions () {} - + const OptionDefinition* GetDefinitions () { @@ -4802,7 +4811,7 @@ public: m_class_name = option_arg; m_sym_ctx_specified = true; break; - + case 'e': m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success); if (!success) @@ -4812,7 +4821,7 @@ public: } m_sym_ctx_specified = true; break; - + case 'l': m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success); if (!success) @@ -4822,17 +4831,17 @@ public: } m_sym_ctx_specified = true; break; - + case 'i': m_no_inlines = true; break; - + case 'n': m_function_name = option_arg; m_func_name_type_mask |= eFunctionNameTypeAuto; m_sym_ctx_specified = true; break; - + case 'f': m_file_name = option_arg; m_sym_ctx_specified = true; @@ -4890,7 +4899,7 @@ public: m_thread_index = UINT32_MAX; m_thread_name.clear(); m_queue_name.clear(); - + m_no_inlines = false; m_sym_ctx_specified = false; m_thread_specified = false; @@ -4899,9 +4908,9 @@ public: m_one_liner.clear(); } - + static OptionDefinition g_option_table[]; - + std::string m_class_name; std::string m_function_name; uint32_t m_line_start; @@ -4942,7 +4951,6 @@ public: } protected: - virtual void IOHandlerActivated (IOHandler &io_handler) { @@ -4953,8 +4961,7 @@ protected: output_sp->Flush(); } } - - + virtual void IOHandlerInputComplete (IOHandler &io_handler, std::string &line) { @@ -4986,12 +4993,12 @@ protected: } io_handler.SetIsDone(true); } - + bool DoExecute (Args& command, CommandReturnObject &result) { m_stop_hook_sp.reset(); - + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); if (target) { @@ -5002,63 +5009,63 @@ protected: if (m_options.m_sym_ctx_specified) { specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget())); - + if (!m_options.m_module_name.empty()) { specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified); } - + if (!m_options.m_class_name.empty()) { specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified); } - + if (!m_options.m_file_name.empty()) { specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified); } - + if (m_options.m_line_start != 0) { specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified); } - + if (m_options.m_line_end != UINT_MAX) { specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); } - + if (!m_options.m_function_name.empty()) { specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified); } } - + if (specifier_ap.get()) new_hook_sp->SetSpecifier (specifier_ap.release()); // Next see if any of the thread options have been entered: - + if (m_options.m_thread_specified) { ThreadSpec *thread_spec = new ThreadSpec(); - + if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) { thread_spec->SetTID (m_options.m_thread_id); } - + if (m_options.m_thread_index != UINT32_MAX) thread_spec->SetIndex (m_options.m_thread_index); - + if (!m_options.m_thread_name.empty()) thread_spec->SetName (m_options.m_thread_name.c_str()); - + if (!m_options.m_queue_name.empty()) thread_spec->SetQueueName (m_options.m_queue_name.c_str()); - + new_hook_sp->SetThreadSpecifier (thread_spec); - + } if (m_options.m_use_one_liner) { @@ -5082,7 +5089,7 @@ protected: result.AppendError ("invalid target\n"); result.SetStatus (eReturnStatusFailed); } - + return result.Succeeded(); } private: @@ -5093,29 +5100,29 @@ private: OptionDefinition CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOneLiner, + { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOneLiner, "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, - { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, + { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the module within which the stop-hook is to be run."}, - { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadIndex, + { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "The stop hook is run only for the thread whose index matches this argument."}, - { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadID, + { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID, "The stop hook is run only for the thread whose TID matches this argument."}, - { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadName, + { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName, "The stop hook is run only for the thread whose thread name matches this argument."}, - { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, 0, eArgTypeQueueName, + { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName, "The stop hook is run only for threads in the queue whose name is given by this argument."}, - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, + { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the source file within which the stop-hook is to be run." }, - { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum, + { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, "Set the start of the line range for which the stop-hook is to be run."}, - { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum, + { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, "Set the end of the line range for which the stop-hook is to be run."}, - { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeClassName, + { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeClassName, "Specify the class within which the stop-hook is to be run." }, - { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, + { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the function name within which the stop hook will be run." }, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; #pragma mark CommandObjectTargetStopHookDelete @@ -5189,7 +5196,7 @@ protected: result.AppendError ("invalid target\n"); result.SetStatus (eReturnStatusFailed); } - + return result.Succeeded(); } }; @@ -5226,7 +5233,7 @@ protected: // FIXME: see if we can use the breakpoint id style parser? size_t num_args = command.GetArgumentCount(); bool success; - + if (num_args == 0) { target->SetAllStopHooksActiveState (m_enable); @@ -5297,7 +5304,7 @@ protected: result.SetStatus (eReturnStatusFailed); return result.Succeeded(); } - + size_t num_hooks = target->GetNumStopHooks (); if (num_hooks == 0) { @@ -5367,7 +5374,7 @@ CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter & "A set of commands for operating on debugger targets.", "target []") { - + LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter))); LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter))); LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter))); diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp index 10d661882c92..e7a8652ac898 100644 --- a/source/Commands/CommandObjectThread.cpp +++ b/source/Commands/CommandObjectThread.cpp @@ -305,10 +305,10 @@ protected: OptionDefinition CommandObjectThreadBacktrace::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"}, -{ LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"}, -{ LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Show the extended backtrace, if available"}, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"}, +{ LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"}, +{ LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Show the extended backtrace, if available"}, +{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; enum StepScope @@ -348,12 +348,37 @@ public: case 'a': { bool success; - m_avoid_no_debug = Args::StringToBoolean (option_arg, true, &success); + bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success); if (!success) error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option); + else + { + m_step_in_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo; + } + } + break; + + case 'A': + { + bool success; + bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success); + if (!success) + error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option); + else + { + m_step_out_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo; + } } break; + case 'c': + { + m_step_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0); + if (m_step_count == UINT32_MAX) + error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); + break; + } + break; case 'm': { OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; @@ -386,10 +411,12 @@ public: void OptionParsingStarting () { - m_avoid_no_debug = true; + m_step_in_avoid_no_debug = eLazyBoolCalculate; + m_step_out_avoid_no_debug = eLazyBoolCalculate; m_run_mode = eOnlyDuringStepping; m_avoid_regexp.clear(); m_step_in_target.clear(); + m_step_count = 1; } const OptionDefinition* @@ -403,10 +430,12 @@ public: static OptionDefinition g_option_table[]; // Instance variables to hold the values for command options. - bool m_avoid_no_debug; + LazyBool m_step_in_avoid_no_debug; + LazyBool m_step_out_avoid_no_debug; RunMode m_run_mode; std::string m_avoid_regexp; std::string m_step_in_target; + int32_t m_step_count; }; CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter, @@ -522,7 +551,9 @@ protected: frame->GetSymbolContext(eSymbolContextEverything), m_options.m_step_in_target.c_str(), stop_other_threads, - m_options.m_avoid_no_debug); + m_options.m_step_in_avoid_no_debug, + m_options.m_step_out_avoid_no_debug); + if (new_plan_sp && !m_options.m_avoid_regexp.empty()) { ThreadPlanStepInRange *step_in_range_plan = static_cast (new_plan_sp.get()); @@ -541,7 +572,8 @@ protected: new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans, frame->GetSymbolContext(eSymbolContextEverything).line_entry.range, frame->GetSymbolContext(eSymbolContextEverything), - stop_other_threads); + stop_other_threads, + m_options.m_step_out_avoid_no_debug); else new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, @@ -564,7 +596,8 @@ protected: bool_stop_other_threads, eVoteYes, eVoteNoOpinion, - thread->GetSelectedFrameIndex()); + thread->GetSelectedFrameIndex(), + m_options.m_step_out_avoid_no_debug); } else { @@ -580,10 +613,22 @@ protected: { new_plan_sp->SetIsMasterPlan (true); new_plan_sp->SetOkayToDiscard (false); + + if (m_options.m_step_count > 1) + { + if (new_plan_sp->SetIterationCount(m_options.m_step_count)) + { + result.AppendWarning ("step operation does not support iteration count."); + } + } process->GetThreadList().SetSelectedThreadByID (thread->GetID()); process->Resume (); - + + // There is a race condition where this thread will return up the call stack to the main command handler + // and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has + // a chance to call PushProcessIOHandler(). + process->SyncIOHandler(2000); if (synchronous_execution) { @@ -639,11 +684,13 @@ g_duo_running_mode[] = OptionDefinition CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_1, false, "avoid-no-debug", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "A boolean value that sets whether step-in will step over functions with no debug information."}, -{ LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."}, -{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', OptionParser::eRequiredArgument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."}, -{ LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."}, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information."}, +{ LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information."}, +{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst."}, +{ LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, NULL, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."}, +{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."}, +{ LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."}, +{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -770,8 +817,9 @@ public: result.AppendMessageWithFormat ("%u, ", thread->GetIndexID()); else result.AppendMessageWithFormat ("%u ", thread->GetIndexID()); - - thread->SetResumeState (eStateRunning); + + const bool override_suspend = true; + thread->SetResumeState (eStateRunning, override_suspend); } else { @@ -802,7 +850,8 @@ public: if (thread == current_thread) { result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID()); - thread->SetResumeState (eStateRunning); + const bool override_suspend = true; + thread->SetResumeState (eStateRunning, override_suspend); } else { @@ -1177,10 +1226,10 @@ protected: OptionDefinition CommandObjectThreadUntil::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"}, -{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"}, -{ LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, g_duo_running_mode, 0, eArgTypeRunMode,"Determine how to run other threads while stepping this one"}, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +{ 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"}, +{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -1305,6 +1354,193 @@ protected: } }; +//------------------------------------------------------------------------- +// CommandObjectThreadInfo +//------------------------------------------------------------------------- + +class CommandObjectThreadInfo : public CommandObjectParsed +{ +public: + + CommandObjectThreadInfo (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "thread info", + "Show an extended summary of information about thread(s) in a process.", + "thread info", + eFlagRequiresProcess | + eFlagTryTargetAPILock | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused), + m_options (interpreter) + { + CommandArgumentEntry arg; + CommandArgumentData thread_idx_arg; + + thread_idx_arg.arg_type = eArgTypeThreadIndex; + thread_idx_arg.arg_repetition = eArgRepeatStar; + + // There is only one variant this argument could be; put it into the argument entry. + arg.push_back (thread_idx_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back (arg); + } + + class CommandOptions : public Options + { + public: + + CommandOptions (CommandInterpreter &interpreter) : + Options (interpreter) + { + OptionParsingStarting (); + } + + void + OptionParsingStarting () + { + m_json = false; + } + + virtual + ~CommandOptions () + { + } + + virtual Error + SetOptionValue (uint32_t option_idx, const char *option_arg) + { + const int short_option = m_getopt_table[option_idx].val; + Error error; + + switch (short_option) + { + case 'j': + m_json = true; + break; + + default: + return Error("invalid short option character '%c'", short_option); + + } + return error; + } + + const OptionDefinition* + GetDefinitions () + { + return g_option_table; + } + + bool m_json; + + static OptionDefinition g_option_table[]; + }; + + virtual + Options * + GetOptions () + { + return &m_options; + } + + + virtual + ~CommandObjectThreadInfo () + { + } + + virtual bool + DoExecute (Args& command, CommandReturnObject &result) + { + result.SetStatus (eReturnStatusSuccessFinishResult); + Stream &strm = result.GetOutputStream(); + + if (command.GetArgumentCount() == 0) + { + Thread *thread = m_exe_ctx.GetThreadPtr(); + if (thread->GetDescription (strm, eDescriptionLevelFull, m_options.m_json)) + { + result.SetStatus (eReturnStatusSuccessFinishResult); + } + } + else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0) + { + Process *process = m_exe_ctx.GetProcessPtr(); + uint32_t idx = 0; + for (ThreadSP thread_sp : process->Threads()) + { + if (idx != 0) + result.AppendMessage(""); + if (!thread_sp->GetDescription (strm, eDescriptionLevelFull, m_options.m_json)) + { + result.AppendErrorWithFormat ("error displaying info for thread: \"0x%4.4x\"\n", idx); + result.SetStatus (eReturnStatusFailed); + return false; + } + ++idx; + } + } + else + { + const size_t num_args = command.GetArgumentCount(); + Process *process = m_exe_ctx.GetProcessPtr(); + Mutex::Locker locker (process->GetThreadList().GetMutex()); + std::vector thread_sps; + + for (size_t i = 0; i < num_args; i++) + { + bool success; + + uint32_t thread_idx = Args::StringToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success); + if (!success) + { + result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i)); + result.SetStatus (eReturnStatusFailed); + return false; + } + + thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx)); + + if (!thread_sps[i]) + { + result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i)); + result.SetStatus (eReturnStatusFailed); + return false; + } + + } + + for (uint32_t i = 0; i < num_args; i++) + { + if (!thread_sps[i]->GetDescription (strm, eDescriptionLevelFull, m_options.m_json)) + { + result.AppendErrorWithFormat ("error displaying info for thread: \"%s\"\n", command.GetArgumentAtIndex(i)); + result.SetStatus (eReturnStatusFailed); + return false; + } + + if (i < num_args - 1) + result.AppendMessage(""); + } + + } + return result.Succeeded(); + } + + CommandOptions m_options; + +}; + +OptionDefinition +CommandObjectThreadInfo::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the thread info in JSON format."}, + + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } +}; + + //------------------------------------------------------------------------- // CommandObjectThreadReturn //------------------------------------------------------------------------- @@ -1477,12 +1713,12 @@ protected: options.SetUnwindOnError(true); options.SetUseDynamic(eNoDynamicValues); - ExecutionResults exe_results = eExecutionSetupError; + ExpressionResults exe_results = eExpressionSetupError; exe_results = target->EvaluateExpression (command, frame_sp.get(), return_valobj_sp, options); - if (exe_results != eExecutionCompleted) + if (exe_results != eExpressionCompleted) { if (return_valobj_sp) result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString()); @@ -1515,8 +1751,8 @@ protected: OptionDefinition CommandObjectThreadReturn::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."}, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."}, +{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -1702,23 +1938,23 @@ protected: OptionDefinition CommandObjectThreadJump::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, + { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file to jump to."}, - { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypeLineNum, + { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, "Specifies the line number to jump to."}, - { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOffset, + { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset, "Jumps by a relative line offset from the current line."}, - { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeAddressOrExpression, + { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Jumps to a specific address."}, { LLDB_OPT_SET_1| LLDB_OPT_SET_2| - LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone,"Allows the PC to leave the current function."}, + LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,"Allows the PC to leave the current function."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -1738,6 +1974,7 @@ CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter & LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter))); LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter))); LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter))); + LoadSubCommand ("info", CommandObjectSP (new CommandObjectThreadInfo (interpreter))); LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( interpreter, "thread step-in", diff --git a/source/Commands/CommandObjectType.cpp b/source/Commands/CommandObjectType.cpp index f1b1d2c1900c..640fd6dd3fa4 100644 --- a/source/Commands/CommandObjectType.cpp +++ b/source/Commands/CommandObjectType.cpp @@ -17,6 +17,8 @@ // C++ Includes +#include "llvm/ADT/StringRef.h" + #include "lldb/Core/ConstString.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/IOHandler.h" @@ -98,7 +100,7 @@ public: static bool WarnOnPotentialUnquotedUnsignedType (Args& command, CommandReturnObject &result) { - for (int idx = 0; idx < command.GetArgumentCount(); idx++) + for (unsigned idx = 0; idx < command.GetArgumentCount(); idx++) { const char* arg = command.GetArgumentAtIndex(idx); if (idx+1 < command.GetArgumentCount()) @@ -204,7 +206,7 @@ public: static const char *g_summary_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" "def function (valobj,internal_dict):\n" " \"\"\"valobj: an SBValue which you want to provide a summary for\n" - " internal_dict: an LLDB support object not to be used\"\"\""; + " internal_dict: an LLDB support object not to be used\"\"\"\n"; StreamFileSP output_sp(io_handler.GetOutputStreamFile()); if (output_sp) @@ -876,13 +878,13 @@ protected: OptionDefinition CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, - { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, - { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, - { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, - { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, - { LLDB_OPT_SET_2, false, "type", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Format variables as if they were of this type."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, + { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, + { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, + { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, + { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, + { LLDB_OPT_SET_2, false, "type", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Format variables as if they were of this type."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -1054,9 +1056,9 @@ protected: OptionDefinition CommandObjectTypeFormatDelete::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Delete from every category."}, - { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Delete from given category."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Delete from every category."}, + { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Delete from given category."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -1182,8 +1184,8 @@ protected: OptionDefinition CommandObjectTypeFormatClear::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Clear every category."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Clear every category."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -1395,8 +1397,8 @@ CommandObjectTypeRXFormatList_LoopCallback ( OptionDefinition CommandObjectTypeFormatList::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; #ifndef LLDB_DISABLE_PYTHON @@ -1814,6 +1816,25 @@ CommandObjectTypeSummaryAdd::DoExecute (Args& command, CommandReturnObject &resu return Execute_StringSummary(command, result); } +static bool +FixArrayTypeNameWithRegex (ConstString &type_name) +{ + llvm::StringRef type_name_ref(type_name.GetStringRef()); + + if (type_name_ref.endswith("[]")) + { + std::string type_name_str(type_name.GetCString()); + type_name_str.resize(type_name_str.length()-2); + if (type_name_str.back() != ' ') + type_name_str.append(" \\[[0-9]+\\]"); + else + type_name_str.append("\\[[0-9]+\\]"); + type_name.SetCString(type_name_str.c_str()); + return true; + } + return false; +} + bool CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name, TypeSummaryImplSP entry, @@ -1826,17 +1847,8 @@ CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name, if (type == eRegularSummary) { - std::string type_name_str(type_name.GetCString()); - if (type_name_str.compare(type_name_str.length() - 2, 2, "[]") == 0) - { - type_name_str.resize(type_name_str.length()-2); - if (type_name_str.back() != ' ') - type_name_str.append(" \\[[0-9]+\\]"); - else - type_name_str.append("\\[[0-9]+\\]"); - type_name.SetCString(type_name_str.c_str()); + if (FixArrayTypeNameWithRegex (type_name)) type = eRegexSummary; - } } if (type == eRegexSummary) @@ -1870,21 +1882,21 @@ CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name, OptionDefinition CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, - { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, - { LLDB_OPT_SET_ALL, false, "no-value", 'v', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't show the value, just show the summary, for this type."}, - { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, - { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, - { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, - { LLDB_OPT_SET_1 , true, "inline-children", 'c', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "If true, inline all child values into summary string."}, - { LLDB_OPT_SET_1 , false, "omit-names", 'O', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "If true, omit value names in the summary display."}, - { LLDB_OPT_SET_2 , true, "summary-string", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeSummaryString, "Summary string used to display text and object contents."}, - { LLDB_OPT_SET_3, false, "python-script", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command."}, - { LLDB_OPT_SET_3, false, "python-function", 'F', OptionParser::eRequiredArgument, NULL, 0, eArgTypePythonFunction, "Give the name of a Python function to use for this type."}, - { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Input Python code to use for this type manually."}, - { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Expand aggregate data types to show children on separate lines."}, - { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "A name for this summary string."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, + { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, + { LLDB_OPT_SET_ALL, false, "no-value", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't show the value, just show the summary, for this type."}, + { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, + { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, + { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, + { LLDB_OPT_SET_1 , true, "inline-children", 'c', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "If true, inline all child values into summary string."}, + { LLDB_OPT_SET_1 , false, "omit-names", 'O', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "If true, omit value names in the summary display."}, + { LLDB_OPT_SET_2 , true, "summary-string", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSummaryString, "Summary string used to display text and object contents."}, + { LLDB_OPT_SET_3, false, "python-script", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command."}, + { LLDB_OPT_SET_3, false, "python-function", 'F', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Give the name of a Python function to use for this type."}, + { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Input Python code to use for this type manually."}, + { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Expand aggregate data types to show children on separate lines."}, + { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "A name for this summary string."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -2049,9 +2061,9 @@ protected: OptionDefinition CommandObjectTypeSummaryDelete::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Delete from every category."}, - { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Delete from given category."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Delete from every category."}, + { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Delete from given category."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; class CommandObjectTypeSummaryClear : public CommandObjectParsed @@ -2176,8 +2188,8 @@ protected: OptionDefinition CommandObjectTypeSummaryClear::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Clear every category."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Clear every category."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -2405,8 +2417,8 @@ CommandObjectTypeRXSummaryList_LoopCallback ( OptionDefinition CommandObjectTypeSummaryList::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -2953,8 +2965,8 @@ CommandObjectTypeFilterRXList_LoopCallback (void* pt2self, OptionDefinition CommandObjectTypeFilterList::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; #ifndef LLDB_DISABLE_PYTHON @@ -3168,8 +3180,8 @@ CommandObjectTypeSynthRXList_LoopCallback (void* pt2self, OptionDefinition CommandObjectTypeSynthList::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; #endif // #ifndef LLDB_DISABLE_PYTHON @@ -3332,9 +3344,9 @@ protected: OptionDefinition CommandObjectTypeFilterDelete::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Delete from every category."}, - { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Delete from given category."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Delete from every category."}, + { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Delete from given category."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; #ifndef LLDB_DISABLE_PYTHON @@ -3498,9 +3510,9 @@ protected: OptionDefinition CommandObjectTypeSynthDelete::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Delete from every category."}, - { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Delete from given category."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Delete from every category."}, + { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Delete from given category."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; #endif // #ifndef LLDB_DISABLE_PYTHON @@ -3629,8 +3641,8 @@ protected: OptionDefinition CommandObjectTypeFilterClear::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Clear every category."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Clear every category."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; #ifndef LLDB_DISABLE_PYTHON @@ -3758,8 +3770,8 @@ protected: OptionDefinition CommandObjectTypeSynthClear::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Clear every category."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Clear every category."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -3897,17 +3909,8 @@ CommandObjectTypeSynthAdd::AddSynth(ConstString type_name, if (type == eRegularSynth) { - std::string type_name_str(type_name.GetCString()); - if (type_name_str.compare(type_name_str.length() - 2, 2, "[]") == 0) - { - type_name_str.resize(type_name_str.length()-2); - if (type_name_str.back() != ' ') - type_name_str.append(" \\[[0-9]+\\]"); - else - type_name_str.append("\\[[0-9]+\\]"); - type_name.SetCString(type_name_str.c_str()); - type = eRegularSynth; - } + if (FixArrayTypeNameWithRegex (type_name)) + type = eRegexSynth; } if (category->AnyMatches(type_name, @@ -3944,14 +3947,14 @@ CommandObjectTypeSynthAdd::AddSynth(ConstString type_name, OptionDefinition CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, - { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, - { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, - { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, - { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypePythonClass, "Use this Python class to produce synthetic children."}, - { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type Python code to generate a class that provides synthetic children."}, - { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, + { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, + { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-tNULL, ype objects."}, + { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, + { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "Use this Python class to produce synthetic children."}, + { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument,NULL, NULL, 0, eArgTypeNone, "Type Python code to generate a class that NULL, provides synthetic children."}, + { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; #endif // #ifndef LLDB_DISABLE_PYTHON @@ -4076,17 +4079,8 @@ private: if (type == eRegularFilter) { - std::string type_name_str(type_name.GetCString()); - if (type_name_str.compare(type_name_str.length() - 2, 2, "[]") == 0) - { - type_name_str.resize(type_name_str.length()-2); - if (type_name_str.back() != ' ') - type_name_str.append(" \\[[0-9]+\\]"); - else - type_name_str.append("\\[[0-9]+\\]"); - type_name.SetCString(type_name_str.c_str()); + if (FixArrayTypeNameWithRegex (type_name)) type = eRegexFilter; - } } if (category->AnyMatches(type_name, @@ -4250,13 +4244,13 @@ protected: OptionDefinition CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, - { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, - { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, - { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, - { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view."}, - { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, + { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, + { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, + { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, + { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view."}, + { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; class CommandObjectTypeFormat : public CommandObjectMultiword diff --git a/source/Commands/CommandObjectWatchpoint.cpp b/source/Commands/CommandObjectWatchpoint.cpp index e55b2ee4d7d8..ca5fe98ccb31 100644 --- a/source/Commands/CommandObjectWatchpoint.cpp +++ b/source/Commands/CommandObjectWatchpoint.cpp @@ -28,6 +28,8 @@ #include "lldb/Symbol/VariableList.h" #include "lldb/Target/Target.h" +#include "llvm/ADT/StringRef.h" + #include using namespace lldb; @@ -62,14 +64,6 @@ CheckTargetForWatchpointOperations(Target *target, CommandReturnObject &result) return true; } -// FIXME: This doesn't seem to be the right place for this functionality. -#include "llvm/ADT/StringRef.h" -static inline void StripLeadingSpaces(llvm::StringRef &Str) -{ - while (!Str.empty() && isspace(Str[0])) - Str = Str.substr(1); -} - // Equivalent class: {"-", "to", "To", "TO"} of range specifier array. static const char* RSA[4] = { "-", "to", "To", "TO" }; @@ -335,16 +329,16 @@ private: OptionDefinition CommandObjectWatchpointList::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, + { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Give a brief description of the watchpoint (no location info)."}, - { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, + { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Give a full description of the watchpoint and its locations."}, - { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, + { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Explain everything we know about the watchpoint (for debugging debugger bugs)." }, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -397,7 +391,7 @@ protected: { // No watchpoint selected; enable all currently set watchpoints. target->EnableAllWatchpoints(); - result.AppendMessageWithFormat("All watchpoints enabled. (%zu watchpoints)\n", num_watchpoints); + result.AppendMessageWithFormat("All watchpoints enabled. (%" PRIu64 " watchpoints)\n", (uint64_t)num_watchpoints); result.SetStatus(eReturnStatusSuccessFinishNoResult); } else @@ -476,7 +470,7 @@ protected: // No watchpoint selected; disable all currently set watchpoints. if (target->DisableAllWatchpoints()) { - result.AppendMessageWithFormat("All watchpoints disabled. (%zu watchpoints)\n", num_watchpoints); + result.AppendMessageWithFormat("All watchpoints disabled. (%" PRIu64 " watchpoints)\n", (uint64_t)num_watchpoints); result.SetStatus(eReturnStatusSuccessFinishNoResult); } else @@ -564,7 +558,7 @@ protected: else { target->RemoveAllWatchpoints(); - result.AppendMessageWithFormat("All watchpoints removed. (%zu watchpoints)\n", num_watchpoints); + result.AppendMessageWithFormat("All watchpoints removed. (%" PRIu64 " watchpoints)\n", (uint64_t)num_watchpoints); } result.SetStatus (eReturnStatusSuccessFinishNoResult); } @@ -706,7 +700,7 @@ protected: if (command.GetArgumentCount() == 0) { target->IgnoreAllWatchpoints(m_options.m_ignore_count); - result.AppendMessageWithFormat("All watchpoints ignored. (%zu watchpoints)\n", num_watchpoints); + result.AppendMessageWithFormat("All watchpoints ignored. (%" PRIu64 " watchpoints)\n", (uint64_t)num_watchpoints); result.SetStatus (eReturnStatusSuccessFinishNoResult); } else @@ -740,8 +734,8 @@ private: OptionDefinition CommandObjectWatchpointIgnore::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, true, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, "Set the number of times this watchpoint is skipped before stopping." }, - { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL } + { LLDB_OPT_SET_ALL, true, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "Set the number of times this watchpoint is skipped before stopping." }, + { 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL } }; @@ -903,8 +897,8 @@ private: OptionDefinition CommandObjectWatchpointModify::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeExpression, "The watchpoint stops only if this condition expression evaluates to true."}, -{ 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The watchpoint stops only if this condition expression evaluates to true."}, +{ 0, false, NULL, 0 , 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- @@ -1099,8 +1093,8 @@ protected: } else { - result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%zu, variable expression='%s').\n", - addr, size, command.GetArgumentAtIndex(0)); + result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%" PRIu64 ", variable expression='%s').\n", + addr, (uint64_t)size, command.GetArgumentAtIndex(0)); if (error.AsCString(NULL)) result.AppendError(error.AsCString()); result.SetStatus(eReturnStatusFailed); @@ -1262,11 +1256,11 @@ protected: options.SetTryAllThreads(true); options.SetTimeoutUsec(0); - ExecutionResults expr_result = target->EvaluateExpression (expr, + ExpressionResults expr_result = target->EvaluateExpression (expr, frame, valobj_sp, options); - if (expr_result != eExecutionCompleted) + if (expr_result != eExpressionCompleted) { result.GetErrorStream().Printf("error: expression evaluation of address to watch failed\n"); result.GetErrorStream().Printf("expression evaluated: %s\n", expr); @@ -1308,8 +1302,8 @@ protected: } else { - result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%zu).\n", - addr, size); + result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%" PRIu64 ").\n", + addr, (uint64_t)size); if (error.AsCString(NULL)) result.AppendError(error.AsCString()); result.SetStatus(eReturnStatusFailed); diff --git a/source/Commands/CommandObjectWatchpointCommand.cpp b/source/Commands/CommandObjectWatchpointCommand.cpp index 0083ff140e5a..f46db7a6a82b 100644 --- a/source/Commands/CommandObjectWatchpointCommand.cpp +++ b/source/Commands/CommandObjectWatchpointCommand.cpp @@ -519,19 +519,19 @@ g_script_option_enumeration[4] = OptionDefinition CommandObjectWatchpointCommandAdd::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOneLiner, + { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOneLiner, "Specify a one-line watchpoint command inline. Be sure to surround it with quotes." }, - { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, + { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Specify whether watchpoint command execution should terminate on error." }, - { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, g_script_option_enumeration, 0, eArgTypeNone, + { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, NULL, g_script_option_enumeration, 0, eArgTypeNone, "Specify the language for the commands - if none is specified, the lldb command interpreter will be used."}, - { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, NULL, 0, eArgTypePythonFunction, + { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Give the name of a Python function to run as command for this watchpoint. Be sure to give a module name if appropriate."}, - { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; //------------------------------------------------------------------------- diff --git a/source/Core/Address.cpp b/source/Core/Address.cpp index 5ac2bcce70f0..fa9197d12b70 100644 --- a/source/Core/Address.cpp +++ b/source/Core/Address.cpp @@ -427,7 +427,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum break; case DumpStyleSectionPointerOffset: - s->Printf("(Section *)%p + ", section_sp.get()); + s->Printf("(Section *)%p + ", static_cast(section_sp.get())); s->Address(m_offset, addr_size); break; diff --git a/source/Core/AddressRange.cpp b/source/Core/AddressRange.cpp index 835a01d82aa4..3505d56b43e2 100644 --- a/source/Core/AddressRange.cpp +++ b/source/Core/AddressRange.cpp @@ -196,7 +196,10 @@ AddressRange::Dump(Stream *s, Target *target, Address::DumpStyle style, Address: void AddressRange::DumpDebug (Stream *s) const { - s->Printf("%p: AddressRange section = %p, offset = 0x%16.16" PRIx64 ", byte_size = 0x%16.16" PRIx64 "\n", this, m_base_addr.GetSection().get(), m_base_addr.GetOffset(), GetByteSize()); + s->Printf("%p: AddressRange section = %p, offset = 0x%16.16" PRIx64 ", byte_size = 0x%16.16" PRIx64 "\n", + static_cast(this), + static_cast(m_base_addr.GetSection().get()), + m_base_addr.GetOffset(), GetByteSize()); } // //bool diff --git a/source/Core/AddressResolverName.cpp b/source/Core/AddressResolverName.cpp index dd22e17402ba..9f3b3f506fe0 100644 --- a/source/Core/AddressResolverName.cpp +++ b/source/Core/AddressResolverName.cpp @@ -148,7 +148,7 @@ AddressResolverName::SearchCallback break; } - // Remove any duplicates between the funcion list and the symbol list + // Remove any duplicates between the function list and the symbol list if (func_list.GetSize()) { for (i = 0; i < func_list.GetSize(); i++) diff --git a/source/Core/ArchSpec.cpp b/source/Core/ArchSpec.cpp index a93f4bd7b5f7..5f010f066408 100644 --- a/source/Core/ArchSpec.cpp +++ b/source/Core/ArchSpec.cpp @@ -14,13 +14,15 @@ #include +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/COFF.h" #include "llvm/Support/ELF.h" #include "llvm/Support/Host.h" -#include "llvm/Support/MachO.h" +#include "lldb/Utility/SafeMachO.h" #include "lldb/Core/RegularExpression.h" +#include "lldb/Core/StringList.h" #include "lldb/Host/Endian.h" -#include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Target/Platform.h" using namespace lldb; @@ -41,13 +43,13 @@ namespace lldb_private { uint32_t max_opcode_byte_size; llvm::Triple::ArchType machine; ArchSpec::Core core; - const char *name; + const char * const name; }; } // This core information can be looked using the ArchSpec::Core as the index -static const CoreDefinition g_core_definitions[ArchSpec::kNumCores] = +static const CoreDefinition g_core_definitions[] = { { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_generic , "arm" }, { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4 , "armv4" }, @@ -76,6 +78,9 @@ static const CoreDefinition g_core_definitions[ArchSpec::kNumCores] = { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv7k , "thumbv7k" }, { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv7m , "thumbv7m" }, { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv7em , "thumbv7em" }, + { eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64, ArchSpec::eCore_arm_arm64 , "arm64" }, + { eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64, ArchSpec::eCore_arm_armv8 , "armv8" }, + { eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64, ArchSpec::eCore_arm_aarch64 , "aarch64" }, { eByteOrderBig , 8, 4, 4, llvm::Triple::mips64 , ArchSpec::eCore_mips64 , "mips64" }, @@ -102,6 +107,7 @@ static const CoreDefinition g_core_definitions[ArchSpec::kNumCores] = { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i386 , "i386" }, { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486 , "i486" }, { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486sx , "i486sx" }, + { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i686 , "i686" }, { eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64 , ArchSpec::eCore_x86_64_x86_64 , "x86_64" }, { eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64 , ArchSpec::eCore_x86_64_x86_64h , "x86_64h" }, @@ -110,9 +116,19 @@ static const CoreDefinition g_core_definitions[ArchSpec::kNumCores] = { eByteOrderLittle, 4, 4, 4, llvm::Triple::hexagon , ArchSpec::eCore_hexagon_hexagonv5, "hexagonv5" }, { eByteOrderLittle, 4, 4, 4 , llvm::Triple::UnknownArch , ArchSpec::eCore_uknownMach32 , "unknown-mach-32" }, - { eByteOrderLittle, 8, 4, 4 , llvm::Triple::UnknownArch , ArchSpec::eCore_uknownMach64 , "unknown-mach-64" } + { eByteOrderLittle, 8, 4, 4 , llvm::Triple::UnknownArch , ArchSpec::eCore_uknownMach64 , "unknown-mach-64" }, + + { eByteOrderLittle, 4, 1, 1 , llvm::Triple::kalimba , ArchSpec::eCore_kalimba , "kalimba" }, + { eByteOrderBig , 4, 1, 1 , llvm::Triple::kalimba , ArchSpec::eCore_kalimba3 , "kalimba3" }, + { eByteOrderLittle, 4, 1, 1 , llvm::Triple::kalimba , ArchSpec::eCore_kalimba4 , "kalimba4" }, + { eByteOrderLittle, 4, 1, 1 , llvm::Triple::kalimba , ArchSpec::eCore_kalimba5 , "kalimba5" } }; +// Ensure that we have an entry in the g_core_definitions for each core. If you comment out an entry above, +// you will need to comment out the corresponding ArchSpec::Core enumeration. +static_assert(sizeof(g_core_definitions) / sizeof(CoreDefinition) == ArchSpec::kNumCores, "make sure we have one core definition for each core"); + + struct ArchDefinitionEntry { ArchSpec::Core core; @@ -137,7 +153,7 @@ ArchSpec::AutoComplete (const char *name, StringList &matches) uint32_t i; if (name && name[0]) { - for (i = 0; i < ArchSpec::kNumCores; ++i) + for (i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) { if (NameMatches(g_core_definitions[i].name, eNameMatchStartsWith, name)) matches.AppendString (g_core_definitions[i].name); @@ -145,7 +161,7 @@ ArchSpec::AutoComplete (const char *name, StringList &matches) } else { - for (i = 0; i < ArchSpec::kNumCores; ++i) + for (i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) matches.AppendString (g_core_definitions[i].name); } return matches.GetSize(); @@ -179,6 +195,10 @@ static const ArchDefinitionEntry g_macho_arch_entries[] = { ArchSpec::eCore_arm_armv7k , llvm::MachO::CPU_TYPE_ARM , 12 , UINT32_MAX , SUBTYPE_MASK }, { ArchSpec::eCore_arm_armv7m , llvm::MachO::CPU_TYPE_ARM , 15 , UINT32_MAX , SUBTYPE_MASK }, { ArchSpec::eCore_arm_armv7em , llvm::MachO::CPU_TYPE_ARM , 16 , UINT32_MAX , SUBTYPE_MASK }, + { ArchSpec::eCore_arm_arm64 , llvm::MachO::CPU_TYPE_ARM64 , CPU_ANY, UINT32_MAX , SUBTYPE_MASK }, + { ArchSpec::eCore_arm_arm64 , llvm::MachO::CPU_TYPE_ARM64 , 0 , UINT32_MAX , SUBTYPE_MASK }, + { ArchSpec::eCore_arm_arm64 , llvm::MachO::CPU_TYPE_ARM64 , 1 , UINT32_MAX , SUBTYPE_MASK }, + { ArchSpec::eCore_arm_arm64 , llvm::MachO::CPU_TYPE_ARM64 , 13 , UINT32_MAX , SUBTYPE_MASK }, { ArchSpec::eCore_thumb , llvm::MachO::CPU_TYPE_ARM , 0 , UINT32_MAX , SUBTYPE_MASK }, { ArchSpec::eCore_thumbv4t , llvm::MachO::CPU_TYPE_ARM , 5 , UINT32_MAX , SUBTYPE_MASK }, { ArchSpec::eCore_thumbv5 , llvm::MachO::CPU_TYPE_ARM , 7 , UINT32_MAX , SUBTYPE_MASK }, @@ -221,7 +241,7 @@ static const ArchDefinitionEntry g_macho_arch_entries[] = }; static const ArchDefinition g_macho_arch_def = { eArchTypeMachO, - sizeof(g_macho_arch_entries)/sizeof(g_macho_arch_entries[0]), + llvm::array_lengthof(g_macho_arch_entries), g_macho_arch_entries, "mach-o" }; @@ -239,33 +259,39 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = { ArchSpec::eCore_ppc_generic , llvm::ELF::EM_PPC , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // PowerPC { ArchSpec::eCore_ppc64_generic , llvm::ELF::EM_PPC64 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // PowerPC64 { ArchSpec::eCore_arm_generic , llvm::ELF::EM_ARM , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARM + { ArchSpec::eCore_arm_aarch64 , llvm::ELF::EM_AARCH64, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARM64 { ArchSpec::eCore_sparc9_generic , llvm::ELF::EM_SPARCV9, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // SPARC V9 { ArchSpec::eCore_x86_64_x86_64 , llvm::ELF::EM_X86_64 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // AMD64 { ArchSpec::eCore_mips64 , llvm::ELF::EM_MIPS , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // MIPS - { ArchSpec::eCore_hexagon_generic , llvm::ELF::EM_HEXAGON, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu } // HEXAGON + { ArchSpec::eCore_hexagon_generic , llvm::ELF::EM_HEXAGON, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // HEXAGON + { ArchSpec::eCore_kalimba , llvm::ELF::EM_CSR_KALIMBA, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // KALIMBA + { ArchSpec::eCore_kalimba3 , llvm::ELF::EM_CSR_KALIMBA, 3, 0xFFFFFFFFu, 0xFFFFFFFFu }, // KALIMBA + { ArchSpec::eCore_kalimba4 , llvm::ELF::EM_CSR_KALIMBA, 4, 0xFFFFFFFFu, 0xFFFFFFFFu }, // KALIMBA + { ArchSpec::eCore_kalimba5 , llvm::ELF::EM_CSR_KALIMBA, 5, 0xFFFFFFFFu, 0xFFFFFFFFu } // KALIMBA + }; static const ArchDefinition g_elf_arch_def = { eArchTypeELF, - sizeof(g_elf_arch_entries)/sizeof(g_elf_arch_entries[0]), + llvm::array_lengthof(g_elf_arch_entries), g_elf_arch_entries, "elf", }; static const ArchDefinitionEntry g_coff_arch_entries[] = { - { ArchSpec::eCore_x86_32_i386 , llvm::COFF::IMAGE_FILE_MACHINE_I386 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // Intel 80386 + { ArchSpec::eCore_x86_32_i386 , llvm::COFF::IMAGE_FILE_MACHINE_I386 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // Intel 80x86 { ArchSpec::eCore_ppc_generic , llvm::COFF::IMAGE_FILE_MACHINE_POWERPC , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // PowerPC { ArchSpec::eCore_ppc_generic , llvm::COFF::IMAGE_FILE_MACHINE_POWERPCFP, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // PowerPC (with FPU) { ArchSpec::eCore_arm_generic , llvm::COFF::IMAGE_FILE_MACHINE_ARM , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARM - { ArchSpec::eCore_arm_armv7 , llvm::COFF::IMAGE_FILE_MACHINE_ARMV7 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARMv7 + { ArchSpec::eCore_arm_armv7 , llvm::COFF::IMAGE_FILE_MACHINE_ARMNT , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARMv7 { ArchSpec::eCore_thumb , llvm::COFF::IMAGE_FILE_MACHINE_THUMB , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARMv7 { ArchSpec::eCore_x86_64_x86_64, llvm::COFF::IMAGE_FILE_MACHINE_AMD64 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu } // AMD64 }; static const ArchDefinition g_coff_arch_def = { eArchTypeCOFF, - sizeof(g_coff_arch_entries)/sizeof(g_coff_arch_entries[0]), + llvm::array_lengthof(g_coff_arch_entries), g_coff_arch_entries, "pe-coff", }; @@ -278,8 +304,7 @@ static const ArchDefinition *g_arch_definitions[] = { &g_coff_arch_def }; -static const size_t k_num_arch_definitions = - sizeof(g_arch_definitions) / sizeof(g_arch_definitions[0]); +static const size_t k_num_arch_definitions = llvm::array_lengthof(g_arch_definitions); //===----------------------------------------------------------------------===// // Static helper functions. @@ -302,7 +327,7 @@ FindArchDefinition (ArchitectureType arch_type) static const CoreDefinition * FindCoreDefinition (llvm::StringRef name) { - for (unsigned int i = 0; i < ArchSpec::kNumCores; ++i) + for (unsigned int i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) { if (name.equals_lower(g_core_definitions[i].name)) return &g_core_definitions[i]; @@ -313,7 +338,7 @@ FindCoreDefinition (llvm::StringRef name) static inline const CoreDefinition * FindCoreDefinition (ArchSpec::Core core) { - if (core >= 0 && core < ArchSpec::kNumCores) + if (core >= 0 && core < llvm::array_lengthof(g_core_definitions)) return &g_core_definitions[core]; return NULL; } @@ -472,6 +497,40 @@ ArchSpec::GetMachOCPUSubType () const return LLDB_INVALID_CPUTYPE; } +uint32_t +ArchSpec::GetDataByteSize () const +{ + switch (m_core) + { + case eCore_kalimba3: + return 3; + case eCore_kalimba4: + return 1; + case eCore_kalimba5: + return 3; + default: + return 1; + } + return 1; +} + +uint32_t +ArchSpec::GetCodeByteSize () const +{ + switch (m_core) + { + case eCore_kalimba3: + return 4; + case eCore_kalimba4: + return 1; + case eCore_kalimba5: + return 1; + default: + return 1; + } + return 1; +} + llvm::Triple::ArchType ArchSpec::GetMachine () const { @@ -605,11 +664,11 @@ ArchSpec::SetTriple (const char *triple_cstr) { // Special case for the current host default architectures... if (triple_stref.equals (LLDB_ARCH_DEFAULT_32BIT)) - *this = Host::GetArchitecture (Host::eSystemDefaultArchitecture32); + *this = HostInfo::GetArchitecture(HostInfo::eArchKind32); else if (triple_stref.equals (LLDB_ARCH_DEFAULT_64BIT)) - *this = Host::GetArchitecture (Host::eSystemDefaultArchitecture64); + *this = HostInfo::GetArchitecture(HostInfo::eArchKind64); else if (triple_stref.equals (LLDB_ARCH_DEFAULT)) - *this = Host::GetArchitecture (Host::eSystemDefaultArchitecture); + *this = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); } else { @@ -636,11 +695,11 @@ ArchSpec::SetTriple (const char *triple_cstr, Platform *platform) { // Special case for the current host default architectures... if (triple_stref.equals (LLDB_ARCH_DEFAULT_32BIT)) - *this = Host::GetArchitecture (Host::eSystemDefaultArchitecture32); + *this = HostInfo::GetArchitecture(HostInfo::eArchKind32); else if (triple_stref.equals (LLDB_ARCH_DEFAULT_64BIT)) - *this = Host::GetArchitecture (Host::eSystemDefaultArchitecture64); + *this = HostInfo::GetArchitecture(HostInfo::eArchKind64); else if (triple_stref.equals (LLDB_ARCH_DEFAULT)) - *this = Host::GetArchitecture (Host::eSystemDefaultArchitecture); + *this = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); } else { @@ -729,6 +788,7 @@ ArchSpec::SetArchitecture (ArchitectureType arch_type, uint32_t cpu, uint32_t su switch (core_def->machine) { + case llvm::Triple::aarch64: case llvm::Triple::arm: case llvm::Triple::thumb: m_triple.setOS (llvm::Triple::IOS); @@ -736,6 +796,15 @@ ArchSpec::SetArchitecture (ArchitectureType arch_type, uint32_t cpu, uint32_t su case llvm::Triple::x86: case llvm::Triple::x86_64: + // Don't set the OS for x86_64 or for x86 as we want to leave it as an "unspecified unknown" + // which means if we ask for the OS from the llvm::Triple we get back llvm::Triple::UnknownOS, but + // if we ask for the string value for the OS it will come back empty (unspecified). + // We do this because we now have iOS and MacOSX as the OS values for x86 and x86_64 for + // normal desktop and simulator binaries. And if we compare a "x86_64-apple-ios" to a "x86_64-apple-" + // triple, it will say it is compatible (because the OS is unspecified in the second one and will match + // anything in the first + break; + default: m_triple.setOS (llvm::Triple::MacOSX); break; @@ -837,6 +906,7 @@ ArchSpec::IsEqualTo (const ArchSpec& rhs, bool exact_match) const if (rhs_os_specified && lhs_os_specified) return false; } + // Only fail if both os types are not unknown if (lhs_triple_os != llvm::Triple::UnknownOS && rhs_triple_os != llvm::Triple::UnknownOS) @@ -893,6 +963,10 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in case ArchSpec::kCore_any: return true; + case ArchSpec::eCore_arm_generic: + if (enforce_exact_match) + break; + // Fall through to case below case ArchSpec::kCore_arm_any: if (core2 >= ArchSpec::kCore_arm_first && core2 <= ArchSpec::kCore_arm_last) return true; @@ -901,17 +975,22 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in if (core2 == ArchSpec::kCore_arm_any) return true; break; - + case ArchSpec::kCore_x86_32_any: if ((core2 >= ArchSpec::kCore_x86_32_first && core2 <= ArchSpec::kCore_x86_32_last) || (core2 == ArchSpec::kCore_x86_32_any)) return true; break; - + + case ArchSpec::kCore_x86_64_any: + if ((core2 >= ArchSpec::kCore_x86_64_first && core2 <= ArchSpec::kCore_x86_64_last) || (core2 == ArchSpec::kCore_x86_64_any)) + return true; + break; + case ArchSpec::kCore_ppc_any: if ((core2 >= ArchSpec::kCore_ppc_first && core2 <= ArchSpec::kCore_ppc_last) || (core2 == ArchSpec::kCore_ppc_any)) return true; break; - + case ArchSpec::kCore_ppc64_any: if ((core2 >= ArchSpec::kCore_ppc64_first && core2 <= ArchSpec::kCore_ppc64_last) || (core2 == ArchSpec::kCore_ppc64_any)) return true; @@ -920,10 +999,13 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in case ArchSpec::eCore_arm_armv6m: if (!enforce_exact_match) { + if (core2 == ArchSpec::eCore_arm_generic) + return true; try_inverse = false; if (core2 == ArchSpec::eCore_arm_armv7) return true; } + break; case ArchSpec::kCore_hexagon_any: if ((core2 >= ArchSpec::kCore_hexagon_first && core2 <= ArchSpec::kCore_hexagon_last) || (core2 == ArchSpec::kCore_hexagon_any)) @@ -937,9 +1019,63 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in case ArchSpec::eCore_arm_armv7s: if (!enforce_exact_match) { - try_inverse = false; + if (core2 == ArchSpec::eCore_arm_generic) + return true; if (core2 == ArchSpec::eCore_arm_armv7) return true; + try_inverse = false; + } + break; + + case ArchSpec::eCore_x86_64_x86_64h: + if (!enforce_exact_match) + { + try_inverse = false; + if (core2 == ArchSpec::eCore_x86_64_x86_64) + return true; + } + break; + + case ArchSpec::eCore_kalimba: + case ArchSpec::eCore_kalimba3: + case ArchSpec::eCore_kalimba4: + case ArchSpec::eCore_kalimba5: + if (core2 >= ArchSpec::kCore_kalimba_first && core2 <= ArchSpec::kCore_kalimba_last) + { + return true; + } + break; + + case ArchSpec::eCore_arm_armv8: + if (!enforce_exact_match) + { + if (core2 == ArchSpec::eCore_arm_arm64) + return true; + if (core2 == ArchSpec::eCore_arm_aarch64) + return true; + try_inverse = false; + } + break; + + case ArchSpec::eCore_arm_aarch64: + if (!enforce_exact_match) + { + if (core2 == ArchSpec::eCore_arm_arm64) + return true; + if (core2 == ArchSpec::eCore_arm_armv8) + return true; + try_inverse = false; + } + break; + + case ArchSpec::eCore_arm_arm64: + if (!enforce_exact_match) + { + if (core2 == ArchSpec::eCore_arm_aarch64) + return true; + if (core2 == ArchSpec::eCore_arm_armv8) + return true; + try_inverse = false; } break; diff --git a/source/Core/Broadcaster.cpp b/source/Core/Broadcaster.cpp index 88f39961832f..dc37516c29c2 100644 --- a/source/Core/Broadcaster.cpp +++ b/source/Core/Broadcaster.cpp @@ -31,15 +31,16 @@ Broadcaster::Broadcaster (BroadcasterManager *manager, const char *name) : { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); if (log) - log->Printf ("%p Broadcaster::Broadcaster(\"%s\")", this, m_broadcaster_name.AsCString()); - + log->Printf ("%p Broadcaster::Broadcaster(\"%s\")", + static_cast(this), m_broadcaster_name.AsCString()); } Broadcaster::~Broadcaster() { Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); if (log) - log->Printf ("%p Broadcaster::~Broadcaster(\"%s\")", this, m_broadcaster_name.AsCString()); + log->Printf ("%p Broadcaster::~Broadcaster(\"%s\")", + static_cast(this), m_broadcaster_name.AsCString()); Clear(); } @@ -226,7 +227,7 @@ Broadcaster::PrivateBroadcastEvent (EventSP &event_sp, bool unique) const uint32_t event_type = event_sp->GetType(); Mutex::Locker event_types_locker(m_listeners_mutex); - + Listener *hijacking_listener = NULL; if (!m_hijacking_listeners.empty()) { @@ -242,11 +243,9 @@ Broadcaster::PrivateBroadcastEvent (EventSP &event_sp, bool unique) StreamString event_description; event_sp->Dump (&event_description); log->Printf ("%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, unique =%i) hijack = %p", - this, - m_broadcaster_name.AsCString(""), - event_description.GetData(), - unique, - hijacking_listener); + static_cast(this), m_broadcaster_name.AsCString(""), + event_description.GetData(), unique, + static_cast(hijacking_listener)); } if (hijacking_listener) @@ -293,16 +292,12 @@ bool Broadcaster::HijackBroadcaster (Listener *listener, uint32_t event_mask) { Mutex::Locker event_types_locker(m_listeners_mutex); - + Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS)); if (log) - { log->Printf ("%p Broadcaster(\"%s\")::HijackBroadcaster (listener(\"%s\")=%p)", - this, - m_broadcaster_name.AsCString(""), - listener->m_name.c_str(), - listener); - } + static_cast(this), m_broadcaster_name.AsCString(""), + listener->m_name.c_str(), static_cast(listener)); m_hijacking_listeners.push_back(listener); m_hijacking_masks.push_back(event_mask); return true; @@ -320,10 +315,9 @@ Broadcaster::RestoreBroadcaster () { Listener *listener = m_hijacking_listeners.back(); log->Printf ("%p Broadcaster(\"%s\")::RestoreBroadcaster (about to pop listener(\"%s\")=%p)", - this, + static_cast(this), m_broadcaster_name.AsCString(""), - listener->m_name.c_str(), - listener); + listener->m_name.c_str(), static_cast(listener)); } m_hijacking_listeners.pop_back(); } diff --git a/source/Core/Communication.cpp b/source/Core/Communication.cpp index f05ce320b5be..d71c9881a6f3 100644 --- a/source/Core/Communication.cpp +++ b/source/Core/Communication.cpp @@ -380,11 +380,24 @@ Communication::ReadThread (lldb::thread_arg_t p) if (comm->GetCloseOnEOF()) done = true; break; + case eConnectionStatusError: // Check GetError() for details + if (error.GetType() == eErrorTypePOSIX && error.GetError() == EIO) + { + // EIO on a pipe is usually caused by remote shutdown + comm->Disconnect (); + done = true; + } + if (log) + error.LogIfError (log, + "%p Communication::ReadFromConnection () => status = %s", + p, + Communication::ConnectionStatusAsCString (status)); + break; case eConnectionStatusNoConnection: // No connection case eConnectionStatusLostConnection: // Lost connection while connected to a valid connection + case eConnectionStatusInterrupted: // Interrupted done = true; // Fall through... - case eConnectionStatusError: // Check GetError() for details case eConnectionStatusTimedOut: // Request timed out if (log) error.LogIfError (log, @@ -433,6 +446,7 @@ Communication::ConnectionStatusAsCString (lldb::ConnectionStatus status) case eConnectionStatusNoConnection: return "no connection"; case eConnectionStatusLostConnection: return "lost connection"; case eConnectionStatusEndOfFile: return "end of file"; + case eConnectionStatusInterrupted: return "interrupted"; } static char unknown_state_string[64]; diff --git a/source/Core/ConnectionFileDescriptor.cpp b/source/Core/ConnectionFileDescriptor.cpp index ed876e52c9af..7c8e98a21129 100644 --- a/source/Core/ConnectionFileDescriptor.cpp +++ b/source/Core/ConnectionFileDescriptor.cpp @@ -16,7 +16,9 @@ #include "lldb/Core/ConnectionFileDescriptor.h" #include "lldb/Host/Config.h" +#include "lldb/Host/IOObject.h" #include "lldb/Host/SocketAddress.h" +#include "lldb/Host/Socket.h" // C Includes #include @@ -24,20 +26,9 @@ #include #include #include + #ifndef LLDB_DISABLE_POSIX -#include -#include -#include -#include -#include -#include #include -#include -#endif -#ifdef _WIN32 -#include "lldb/Host/windows/windows.h" -#include -#include #endif // C++ Includes @@ -48,84 +39,44 @@ #endif // Project includes #include "lldb/lldb-private-log.h" -#include "lldb/Interpreter/Args.h" #include "lldb/Core/Communication.h" #include "lldb/Core/Log.h" -#include "lldb/Core/RegularExpression.h" #include "lldb/Core/Timer.h" #include "lldb/Host/Host.h" +#include "lldb/Host/Socket.h" +#include "lldb/Interpreter/Args.h" using namespace lldb; using namespace lldb_private; -static bool -DecodeHostAndPort (const char *host_and_port, - std::string &host_str, - std::string &port_str, - int32_t& port, - Error *error_ptr) -{ - static RegularExpression g_regex ("([^:]+):([0-9]+)"); - RegularExpression::Match regex_match(2); - if (g_regex.Execute (host_and_port, ®ex_match)) - { - if (regex_match.GetMatchAtIndex (host_and_port, 1, host_str) && - regex_match.GetMatchAtIndex (host_and_port, 2, port_str)) - { - port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN); - if (port != INT32_MIN) - { - if (error_ptr) - error_ptr->Clear(); - return true; - } - } - } - host_str.clear(); - port_str.clear(); - port = INT32_MIN; - if (error_ptr) - error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port); - return false; -} - ConnectionFileDescriptor::ConnectionFileDescriptor () : Connection(), - m_fd_send (-1), - m_fd_recv (-1), - m_fd_send_type (eFDTypeFile), - m_fd_recv_type (eFDTypeFile), - m_udp_send_sockaddr (new SocketAddress()), - m_socket_timeout_usec(0), - m_pipe_read(-1), - m_pipe_write(-1), + m_pipe (), m_mutex (Mutex::eMutexTypeRecursive), - m_should_close_fd (false), - m_shutting_down (false) + m_shutting_down (false), + m_waiting_for_accept (false) { Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT)); if (log) - log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor ()", this); + log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor ()", + static_cast(this)); } ConnectionFileDescriptor::ConnectionFileDescriptor (int fd, bool owns_fd) : Connection(), - m_fd_send (fd), - m_fd_recv (fd), - m_fd_send_type (eFDTypeFile), - m_fd_recv_type (eFDTypeFile), - m_udp_send_sockaddr (new SocketAddress()), - m_socket_timeout_usec(0), - m_pipe_read(-1), - m_pipe_write(-1), + m_pipe (), m_mutex (Mutex::eMutexTypeRecursive), - m_should_close_fd (owns_fd), - m_shutting_down (false) + m_shutting_down (false), + m_waiting_for_accept (false) { + m_write_sp.reset(new File(fd, owns_fd)); + m_read_sp.reset(new File(fd, false)); + Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT)); if (log) - log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)", this, fd, owns_fd); + log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)", + static_cast(this), fd, owns_fd); OpenCommandPipe (); } @@ -134,7 +85,8 @@ ConnectionFileDescriptor::~ConnectionFileDescriptor () { Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT)); if (log) - log->Printf ("%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()", this); + log->Printf ("%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()", + static_cast(this)); Disconnect (NULL); CloseCommandPipe (); } @@ -143,31 +95,22 @@ void ConnectionFileDescriptor::OpenCommandPipe () { CloseCommandPipe(); - + Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); // Make the command file descriptor here: - int filedes[2]; -#ifndef LLDB_DISABLE_POSIX - int result = pipe (filedes); -#else - int result = -1; -#endif - if (result != 0) + if (!m_pipe.Open()) { if (log) log->Printf ("%p ConnectionFileDescriptor::OpenCommandPipe () - could not make pipe: %s", - this, - strerror(errno)); + static_cast(this), strerror(errno)); } else { - m_pipe_read = filedes[0]; - m_pipe_write = filedes[1]; if (log) log->Printf ("%p ConnectionFileDescriptor::OpenCommandPipe() - success readfd=%d writefd=%d", - this, - m_pipe_read, - m_pipe_write); + static_cast(this), + m_pipe.GetReadFileDescriptor(), + m_pipe.GetWriteFileDescriptor()); } } @@ -177,33 +120,15 @@ ConnectionFileDescriptor::CloseCommandPipe () Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); if (log) log->Printf ("%p ConnectionFileDescriptor::CloseCommandPipe()", - this); + static_cast(this)); - if (m_pipe_read != -1) - { -#ifdef _MSC_VER - llvm_unreachable("pipe close unsupported in MSVC"); -#else - close (m_pipe_read); -#endif - m_pipe_read = -1; - } - - if (m_pipe_write != -1) - { -#ifdef _MSC_VER - llvm_unreachable("pipe close unsupported in MSVC"); -#else - close (m_pipe_write); -#endif - m_pipe_write = -1; - } + m_pipe.Close(); } bool ConnectionFileDescriptor::IsConnected () const { - return m_fd_send >= 0 || m_fd_recv >= 0; + return (m_read_sp && m_read_sp->IsValid()) || (m_write_sp && m_write_sp->IsValid()); } ConnectionStatus @@ -212,47 +137,52 @@ ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr) Mutex::Locker locker (m_mutex); Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); if (log) - log->Printf ("%p ConnectionFileDescriptor::Connect (url = '%s')", this, s); + log->Printf ("%p ConnectionFileDescriptor::Connect (url = '%s')", + static_cast(this), s); OpenCommandPipe(); - + if (s && s[0]) { - if (strstr(s, "listen://")) + if (strstr(s, "listen://") == s) { // listen://HOST:PORT return SocketListen (s + strlen("listen://"), error_ptr); } - else if (strstr(s, "accept://")) + else if (strstr(s, "accept://") == s) { // unix://SOCKNAME return NamedSocketAccept (s + strlen("accept://"), error_ptr); } - else if (strstr(s, "unix-accept://")) + else if (strstr(s, "unix-accept://") == s) { // unix://SOCKNAME return NamedSocketAccept (s + strlen("unix-accept://"), error_ptr); } - else if (strstr(s, "connect://")) + else if (strstr(s, "connect://") == s) { return ConnectTCP (s + strlen("connect://"), error_ptr); } - else if (strstr(s, "tcp-connect://")) + else if (strstr(s, "tcp-connect://") == s) { return ConnectTCP (s + strlen("tcp-connect://"), error_ptr); } - else if (strstr(s, "udp://")) + else if (strstr(s, "udp://") == s) { return ConnectUDP (s + strlen("udp://"), error_ptr); } - else if (strstr(s, "fd://")) +#ifndef LLDB_DISABLE_POSIX + else if (strstr(s, "fd://") == s) { + if (error_ptr) + error_ptr->SetErrorStringWithFormat ("Protocol is not supported on non-posix hosts '%s'", s); + return eConnectionStatusError; // Just passing a native file descriptor within this current process // that is already opened (possibly from a service or other source). s += strlen ("fd://"); bool success = false; - m_fd_send = m_fd_recv = Args::StringToSInt32 (s, -1, 0, &success); - + int fd = Args::StringToSInt32 (s, -1, 0, &success); + if (success) { // We have what looks to be a valid file descriptor, but we @@ -260,26 +190,17 @@ ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr) // get the flags from the file descriptor and making sure it // isn't a bad fd. errno = 0; -#ifndef LLDB_DISABLE_POSIX - int flags = ::fcntl (m_fd_send, F_GETFL, 0); -#else - int flags = -1; -#endif + int flags = ::fcntl (fd, F_GETFL, 0); if (flags == -1 || errno == EBADF) { if (error_ptr) error_ptr->SetErrorStringWithFormat ("stale file descriptor: %s", s); - m_fd_send = m_fd_recv = -1; + m_read_sp.reset(); + m_write_sp.reset(); return eConnectionStatusError; } else { - // Try and get a socket option from this file descriptor to - // see if this is a socket and set m_is_socket accordingly. - int resuse; - bool is_socket = GetSocketOption (m_fd_send, SOL_SOCKET, SO_REUSEADDR, resuse) == 0; - if (is_socket) - m_fd_send_type = m_fd_recv_type = eFDTypeSocket; // Don't take ownership of a file descriptor that gets passed // to us since someone else opened the file descriptor and // handed it to us. @@ -289,37 +210,55 @@ ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr) // option be "owns=1" or "owns=0" or something like this to // allow us to specify this. For now, we assume we must // assume we don't own it. - m_should_close_fd = false; + + std::unique_ptr tcp_socket; + tcp_socket.reset(new Socket(fd, Socket::ProtocolTcp, false)); + // Try and get a socket option from this file descriptor to + // see if this is a socket and set m_is_socket accordingly. + int resuse; + bool is_socket = !!tcp_socket->GetOption(SOL_SOCKET, SO_REUSEADDR, resuse); + if (is_socket) + { + m_read_sp = std::move(tcp_socket); + m_write_sp = m_read_sp; + } + else + { + m_read_sp.reset(new File(fd, false)); + m_write_sp.reset(new File(fd, false)); + } return eConnectionStatusSuccess; } } - + if (error_ptr) error_ptr->SetErrorStringWithFormat ("invalid file descriptor: \"fd://%s\"", s); - m_fd_send = m_fd_recv = -1; + m_read_sp.reset(); + m_write_sp.reset(); return eConnectionStatusError; } - else if (strstr(s, "file://")) + else if (strstr(s, "file://") == s) { // file:///PATH const char *path = s + strlen("file://"); -#ifndef LLDB_DISABLE_POSIX + int fd = -1; do { - m_fd_send = m_fd_recv = ::open (path, O_RDWR); - } while (m_fd_send == -1 && errno == EINTR); - if (m_fd_send == -1) + fd = ::open (path, O_RDWR); + } while (fd == -1 && errno == EINTR); + + if (fd == -1) { if (error_ptr) error_ptr->SetErrorToErrno(); return eConnectionStatusError; } - if (::isatty(m_fd_send)) + if (::isatty(fd)) { // Set up serial terminal emulation struct termios options; - ::tcgetattr (m_fd_send, &options); + ::tcgetattr (fd, &options); // Set port speed to maximum ::cfsetospeed (&options, B115200); @@ -332,24 +271,23 @@ ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr) options.c_cc[VMIN] = 1; options.c_cc[VTIME] = 0; - ::tcsetattr (m_fd_send, TCSANOW, &options); + ::tcsetattr (fd, TCSANOW, &options); } - int flags = ::fcntl (m_fd_send, F_GETFL, 0); + int flags = ::fcntl (fd, F_GETFL, 0); if (flags >= 0) { if ((flags & O_NONBLOCK) == 0) { flags |= O_NONBLOCK; - ::fcntl (m_fd_send, F_SETFL, flags); + ::fcntl (fd, F_SETFL, flags); } } - m_should_close_fd = true; + m_read_sp.reset(new File(fd, true)); + m_write_sp.reset(new File(fd, false)); return eConnectionStatusSuccess; -#else - return eConnectionStatusError; -#endif } +#endif if (error_ptr) error_ptr->SetErrorStringWithFormat ("unsupported connection URL: '%s'", s); return eConnectionStatusError; @@ -359,81 +297,70 @@ ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr) return eConnectionStatusError; } +bool +ConnectionFileDescriptor::InterruptRead() +{ + return m_pipe.Write("i", 1) == 1; +} + ConnectionStatus ConnectionFileDescriptor::Disconnect (Error *error_ptr) { Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); if (log) - log->Printf ("%p ConnectionFileDescriptor::Disconnect ()", this); - - // Reset the port predicate when disconnecting and don't broadcast - m_port_predicate.SetValue(0, eBroadcastNever); + log->Printf ("%p ConnectionFileDescriptor::Disconnect ()", + static_cast(this)); ConnectionStatus status = eConnectionStatusSuccess; - if (m_fd_send < 0 && m_fd_recv < 0) + if (!IsConnected()) { if (log) - log->Printf ("%p ConnectionFileDescriptor::Disconnect(): Nothing to disconnect", this); + log->Printf ("%p ConnectionFileDescriptor::Disconnect(): Nothing to disconnect", + static_cast(this)); return eConnectionStatusSuccess; } - + + if (m_read_sp && m_read_sp->IsValid() && m_read_sp->GetFdType() == IOObject::eFDTypeSocket) + static_cast(*m_read_sp).PreDisconnect(); + // Try to get the ConnectionFileDescriptor's mutex. If we fail, that is quite likely // because somebody is doing a blocking read on our file descriptor. If that's the case, // then send the "q" char to the command file channel so the read will wake up and the connection // will then know to shut down. - + m_shutting_down = true; - + Mutex::Locker locker; - bool got_lock= locker.TryLock (m_mutex); - + bool got_lock = locker.TryLock (m_mutex); + if (!got_lock) { - if (m_pipe_write != -1 ) + if (m_pipe.WriteDescriptorIsValid()) { int result; - result = write (m_pipe_write, "q", 1); + result = m_pipe.Write("q", 1) == 1; if (log) - log->Printf ("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the lock, sent 'q' to %d, result = %d.", this, m_pipe_write, result); + log->Printf ("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the lock, sent 'q' to %d, result = %d.", + static_cast(this), m_pipe.GetWriteFileDescriptor(), result); } else if (log) - log->Printf ("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the lock, but no command pipe is available.", this); - locker.Lock (m_mutex); - } - - if (m_should_close_fd == true) - { - if (m_fd_send == m_fd_recv) - { - status = Close (m_fd_send, m_fd_send_type, error_ptr); - } - else { - // File descriptors are the different, close both if needed - if (m_fd_send >= 0) - status = Close (m_fd_send, m_fd_send_type, error_ptr); - if (m_fd_recv >= 0) - { - ConnectionStatus recv_status = Close (m_fd_recv, m_fd_recv_type, error_ptr); - if (status == eConnectionStatusSuccess) - status = recv_status; - } + log->Printf ("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the lock, but no command pipe is available.", + static_cast(this)); } + locker.Lock (m_mutex); } - // Now set all our descriptors to invalid values. - - m_fd_send = m_fd_recv = -1; + Error error = m_read_sp->Close(); + Error error2 = m_write_sp->Close(); + if (error.Fail() || error2.Fail()) + status = eConnectionStatusError; + if (error_ptr) + *error_ptr = error.Fail() ? error : error2; - if (status != eConnectionStatusSuccess) - { - - return status; - } - m_shutting_down = false; - return eConnectionStatusSuccess; + return status; } size_t @@ -444,9 +371,6 @@ ConnectionFileDescriptor::Read (void *dst, Error *error_ptr) { Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); - if (log) - log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %" PRIu64 ")...", - this, m_fd_recv, dst, (uint64_t)dst_len); Mutex::Locker locker; bool got_lock = locker.TryLock (m_mutex); @@ -454,67 +378,40 @@ ConnectionFileDescriptor::Read (void *dst, { if (log) log->Printf ("%p ConnectionFileDescriptor::Read () failed to get the connection lock.", - this); + static_cast(this)); if (error_ptr) error_ptr->SetErrorString ("failed to get the connection lock for read."); - + status = eConnectionStatusTimedOut; return 0; } else if (m_shutting_down) return eConnectionStatusError; - - ssize_t bytes_read = 0; status = BytesAvailable (timeout_usec, error_ptr); - if (status == eConnectionStatusSuccess) - { - do - { -#ifndef LLDB_DISABLE_POSIX - bytes_read = ::read (m_fd_recv, dst, dst_len); -#else - switch (m_fd_send_type) { - case eFDTypeSocket: - case eFDTypeSocketUDP: - bytes_read = ::recv (m_fd_recv, (char*)dst, dst_len, 0); - break; - default: - bytes_read = -1; - break; - - } - -#endif - } while (bytes_read < 0 && errno == EINTR); - } - if (status != eConnectionStatusSuccess) return 0; Error error; + size_t bytes_read = dst_len; + error = m_read_sp->Read(dst, bytes_read); + + if (log) + { + log->Printf("%p ConnectionFileDescriptor::Read() fd = %" PRIu64 ", dst = %p, dst_len = %" PRIu64 ") => %" PRIu64 ", error = %s", + static_cast(this), + static_cast(m_read_sp->GetWaitableHandle()), + static_cast(dst), + static_cast(dst_len), + static_cast(bytes_read), + error.AsCString()); + } + if (bytes_read == 0) { error.Clear(); // End-of-file. Do not automatically close; pass along for the end-of-file handlers. status = eConnectionStatusEndOfFile; } - else if (bytes_read < 0) - { - error.SetErrorToErrno(); - } - else - { - error.Clear(); - } - - if (log) - log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %" PRIu64 ") => %" PRIi64 ", error = %s", - this, - m_fd_recv, - dst, - (uint64_t)dst_len, - (int64_t)bytes_read, - error.AsCString()); if (error_ptr) *error_ptr = error; @@ -525,7 +422,7 @@ ConnectionFileDescriptor::Read (void *dst, switch (error_value) { case EAGAIN: // The file was marked for non-blocking I/O, and no data were ready to be read. - if (m_fd_recv_type == eFDTypeSocket || m_fd_recv_type == eFDTypeSocketUDP) + if (m_read_sp->GetFdType() == IOObject::eFDTypeSocket) status = eConnectionStatusTimedOut; else status = eConnectionStatusSuccess; @@ -562,7 +459,8 @@ ConnectionFileDescriptor::Read (void *dst, default: if (log) - log->Printf("%p ConnectionFileDescriptor::Read (), unexpected error: %s", this, strerror(error_value)); + log->Printf("%p ConnectionFileDescriptor::Read (), unexpected error: %s", + static_cast(this), strerror(error_value)); status = eConnectionStatusError; break; // Break to close.... @@ -578,7 +476,9 @@ ConnectionFileDescriptor::Write (const void *src, size_t src_len, ConnectionStat { Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); if (log) - log->Printf ("%p ConnectionFileDescriptor::Write (src = %p, src_len = %" PRIu64 ")", this, src, (uint64_t)src_len); + log->Printf ("%p ConnectionFileDescriptor::Write (src = %p, src_len = %" PRIu64 ")", + static_cast(this), static_cast(src), + static_cast(src_len)); if (!IsConnected ()) { @@ -591,78 +491,18 @@ ConnectionFileDescriptor::Write (const void *src, size_t src_len, ConnectionStat Error error; - ssize_t bytes_sent = 0; - - switch (m_fd_send_type) - { -#ifndef LLDB_DISABLE_POSIX - case eFDTypeFile: // Other FD requireing read/write - do - { - bytes_sent = ::write (m_fd_send, src, src_len); - } while (bytes_sent < 0 && errno == EINTR); - break; -#endif - case eFDTypeSocket: // Socket requiring send/recv - do - { - bytes_sent = ::send (m_fd_send, (char*)src, src_len, 0); - } while (bytes_sent < 0 && errno == EINTR); - break; - - case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom - assert (m_udp_send_sockaddr->GetFamily() != 0); - do - { - bytes_sent = ::sendto (m_fd_send, - (char*)src, - src_len, - 0, - *m_udp_send_sockaddr, - m_udp_send_sockaddr->GetLength()); - } while (bytes_sent < 0 && errno == EINTR); - break; - } - - if (bytes_sent < 0) - error.SetErrorToErrno (); - else - error.Clear (); + size_t bytes_sent = src_len; + error = m_write_sp->Write(src, bytes_sent); if (log) { - switch (m_fd_send_type) - { - case eFDTypeFile: // Other FD requireing read/write - log->Printf ("%p ConnectionFileDescriptor::Write() ::write (fd = %i, src = %p, src_len = %" PRIu64 ") => %" PRIi64 " (error = %s)", - this, - m_fd_send, - src, - (uint64_t)src_len, - (int64_t)bytes_sent, - error.AsCString()); - break; - - case eFDTypeSocket: // Socket requiring send/recv - log->Printf ("%p ConnectionFileDescriptor::Write() ::send (socket = %i, src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)", - this, - m_fd_send, - src, - (uint64_t)src_len, - (int64_t)bytes_sent, - error.AsCString()); - break; - - case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom - log->Printf ("%p ConnectionFileDescriptor::Write() ::sendto (socket = %i, src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)", - this, - m_fd_send, - src, - (uint64_t)src_len, - (int64_t)bytes_sent, - error.AsCString()); - break; - } + log->Printf ("%p ConnectionFileDescriptor::Write(fd = %" PRIu64 ", src = %p, src_len = %" PRIu64 ") => %" PRIu64 " (error = %s)", + static_cast(this), + static_cast(m_write_sp->GetWaitableHandle()), + static_cast(src), + static_cast(src_len), + static_cast(bytes_sent), + error.AsCString()); } if (error_ptr) @@ -696,34 +536,43 @@ ConnectionFileDescriptor::Write (const void *src, size_t src_len, ConnectionStat -#if defined(__APPLE__) - // This ConnectionFileDescriptor::BytesAvailable() uses select(). // // PROS: // - select is consistent across most unix platforms -// - this Apple specific version allows for unlimited fds in the fd_sets by +// - The Apple specific version allows for unlimited fds in the fd_sets by // setting the _DARWIN_UNLIMITED_SELECT define prior to including the // required header files. - // CONS: -// - Darwin only +// - on non-Apple platforms, only supports file descriptors up to FD_SETSIZE. +// This implementation will assert if it runs into that hard limit to let +// users know that another ConnectionFileDescriptor::BytesAvailable() should +// be used or a new version of ConnectionFileDescriptor::BytesAvailable() +// should be written for the system that is running into the limitations. + +#if defined(__APPLE__) +#define FD_SET_DATA(fds) fds.data() +#else +#define FD_SET_DATA(fds) &fds +#endif ConnectionStatus ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_ptr) { // Don't need to take the mutex here separately since we are only called from Read. If we // ever get used more generally we will need to lock here as well. - - Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_CONNECTION)); if (log) - log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", this, timeout_usec); + log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", + static_cast(this), timeout_usec); + struct timeval *tv_ptr; struct timeval tv; if (timeout_usec == UINT32_MAX) { - // Infinite wait... - tv_ptr = NULL; + // Inifinite wait... + tv_ptr = nullptr; } else { @@ -733,20 +582,32 @@ ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_pt tv.tv_usec = time_value.microseconds(); tv_ptr = &tv; } - + // Make a copy of the file descriptors to make sure we don't // have another thread change these values out from under us // and cause problems in the loop below where like in FS_SET() - const int data_fd = m_fd_recv; - const int pipe_fd = m_pipe_read; - - if (data_fd >= 0) + const IOObject::WaitableHandle handle = m_read_sp->GetWaitableHandle(); + const int pipe_fd = m_pipe.GetReadFileDescriptor(); + + if (handle != IOObject::kInvalidHandleValue) { +#if defined(_MSC_VER) + // select() won't accept pipes on Windows. The entire Windows codepath needs to be + // converted over to using WaitForMultipleObjects and event HANDLEs, but for now at least + // this will allow ::select() to not return an error. + const bool have_pipe_fd = false; +#else const bool have_pipe_fd = pipe_fd >= 0; - - while (data_fd == m_fd_recv) +#if !defined(__APPLE__) + assert (handle < FD_SETSIZE); + if (have_pipe_fd) + assert (pipe_fd < FD_SETSIZE); +#endif +#endif + while (handle == m_read_sp->GetWaitableHandle()) { - const int nfds = std::max(data_fd, pipe_fd) + 1; + const int nfds = std::max(handle, pipe_fd) + 1; +#if defined(__APPLE__) llvm::SmallVector read_fds; read_fds.resize((nfds/FD_SETSIZE) + 1); for (size_t i=0; iPrintf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p)...", - this, nfds, data_fd, pipe_fd, tv_ptr); + static_cast(this), nfds, handle, pipe_fd, + static_cast(tv_ptr)); else log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p)...", - this, nfds, data_fd, tv_ptr); + static_cast(this), nfds, handle, + static_cast(tv_ptr)); } - - const int num_set_fds = ::select (nfds, read_fds.data(), NULL, NULL, tv_ptr); + + const int num_set_fds = ::select (nfds, FD_SET_DATA(read_fds), NULL, NULL, tv_ptr); if (num_set_fds < 0) error.SetErrorToErrno(); else error.Clear(); - + if (log) { if (have_pipe_fd) log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p) => %d, error = %s", - this, nfds, data_fd, pipe_fd, tv_ptr, num_set_fds, error.AsCString()); + static_cast(this), nfds, handle, + pipe_fd, static_cast(tv_ptr), num_set_fds, + error.AsCString()); else log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p) => %d, error = %s", - this, nfds, data_fd, tv_ptr, num_set_fds, error.AsCString()); + static_cast(this), nfds, handle, + static_cast(tv_ptr), num_set_fds, + error.AsCString()); } - + if (error_ptr) *error_ptr = error; - + if (error.Fail()) { switch (error.GetError()) { case EBADF: // One of the descriptor sets specified an invalid descriptor. return eConnectionStatusLostConnection; - + case EINVAL: // The specified time limit is invalid. One of its components is negative or too large. default: // Other unknown error return eConnectionStatusError; - + case EAGAIN: // The kernel was (perhaps temporarily) unable to // allocate the requested number of file descriptors, // or we have non-blocking IO @@ -815,903 +686,121 @@ ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_pt } else if (num_set_fds > 0) { - // FD_ISSET is happy to deal with a something larger than - // a single fd_set. - if (FD_ISSET(data_fd, read_fds.data())) + if (FD_ISSET(handle, FD_SET_DATA(read_fds))) return eConnectionStatusSuccess; - if (have_pipe_fd && FD_ISSET(pipe_fd, read_fds.data())) + if (have_pipe_fd && FD_ISSET(pipe_fd, FD_SET_DATA(read_fds))) { // We got a command to exit. Read the data from that pipe: char buffer[16]; ssize_t bytes_read; - + do { bytes_read = ::read (pipe_fd, buffer, sizeof(buffer)); } while (bytes_read < 0 && errno == EINTR); - assert (bytes_read == 1 && buffer[0] == 'q'); - if (log) - log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.", - this, (int) bytes_read, buffer); - - return eConnectionStatusEndOfFile; + switch (buffer[0]) + { + case 'q': + if (log) + log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.", + static_cast(this), + static_cast(bytes_read), buffer); + return eConnectionStatusEndOfFile; + case 'i': + // Interrupt the current read + return eConnectionStatusInterrupted; + } } } } } - + if (error_ptr) error_ptr->SetErrorString("not connected"); return eConnectionStatusLostConnection; } -#else +ConnectionStatus +ConnectionFileDescriptor::NamedSocketAccept (const char *socket_name, Error *error_ptr) +{ + Socket* socket = nullptr; + Error error = Socket::UnixDomainAccept(socket_name, socket); + if (error_ptr) + *error_ptr = error; + m_write_sp.reset(socket); + m_read_sp = m_write_sp; + return (error.Success()) ? eConnectionStatusSuccess : eConnectionStatusError; +} -// This ConnectionFileDescriptor::BytesAvailable() uses select(). -// -// PROS: -// - select is consistent across most unix platforms -// CONS: -// - only supports file descriptors up to FD_SETSIZE. This implementation -// will assert if it runs into that hard limit to let users know that -// another ConnectionFileDescriptor::BytesAvailable() should be used -// or a new version of ConnectionFileDescriptor::BytesAvailable() should -// be written for the system that is running into the limitations. MacOSX -// uses kqueues, and there is a poll() based implementation below. +ConnectionStatus +ConnectionFileDescriptor::NamedSocketConnect (const char *socket_name, Error *error_ptr) +{ + Socket* socket = nullptr; + Error error = Socket::UnixDomainConnect(socket_name, socket); + if (error_ptr) + *error_ptr = error; + m_write_sp.reset(socket); + m_read_sp = m_write_sp; + return (error.Success()) ? eConnectionStatusSuccess : eConnectionStatusError; +} ConnectionStatus -ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_ptr) +ConnectionFileDescriptor::SocketListen(const char *s, Error *error_ptr) { - // Don't need to take the mutex here separately since we are only called from Read. If we - // ever get used more generally we will need to lock here as well. - - Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); - if (log) - log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", this, timeout_usec); - struct timeval *tv_ptr; - struct timeval tv; - if (timeout_usec == UINT32_MAX) - { - // Infinite wait... - tv_ptr = NULL; - } - else - { - TimeValue time_value; - time_value.OffsetWithMicroSeconds (timeout_usec); - tv.tv_sec = time_value.seconds(); - tv.tv_usec = time_value.microseconds(); - tv_ptr = &tv; - } - - // Make a copy of the file descriptors to make sure we don't - // have another thread change these values out from under us - // and cause problems in the loop below where like in FS_SET() - const int data_fd = m_fd_recv; - const int pipe_fd = m_pipe_read; + m_port_predicate.SetValue(0, eBroadcastNever); - if (data_fd >= 0) - { - // If this assert fires off on MacOSX, we will need to switch to using - // libdispatch to read from file descriptors because poll() is causing - // kernel panics and if we exceed FD_SETSIZE we will have no choice... -#ifndef _MSC_VER - assert (data_fd < FD_SETSIZE); -#endif - - const bool have_pipe_fd = pipe_fd >= 0; - - if (have_pipe_fd) - { - assert (pipe_fd < FD_SETSIZE); - } + Socket* socket = nullptr; + m_waiting_for_accept = true; + Error error = Socket::TcpListen(s, socket, &m_port_predicate); + if (error_ptr) + *error_ptr = error; + if (error.Fail()) + return eConnectionStatusError; - while (data_fd == m_fd_recv) - { - fd_set read_fds; - FD_ZERO (&read_fds); - FD_SET (data_fd, &read_fds); - if (have_pipe_fd) - FD_SET (pipe_fd, &read_fds); + std::unique_ptr listening_socket_up; - const int nfds = std::max(data_fd, pipe_fd) + 1; + listening_socket_up.reset(socket); + socket = nullptr; + error = listening_socket_up->BlockingAccept(s, socket); + listening_socket_up.reset(); + if (error_ptr) + *error_ptr = error; + if (error.Fail()) + return eConnectionStatusError; - Error error; - - if (log) - { - if (have_pipe_fd) - log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p)...", - this, nfds, data_fd, pipe_fd, tv_ptr); - else - log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p)...", - this, nfds, data_fd, tv_ptr); - } - - const int num_set_fds = ::select (nfds, &read_fds, NULL, NULL, tv_ptr); - if (num_set_fds < 0) - error.SetErrorToErrno(); - else - error.Clear(); - - if (log) - { - if (have_pipe_fd) - log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p) => %d, error = %s", - this, nfds, data_fd, pipe_fd, tv_ptr, num_set_fds, error.AsCString()); - else - log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p) => %d, error = %s", - this, nfds, data_fd, tv_ptr, num_set_fds, error.AsCString()); - } - - if (error_ptr) - *error_ptr = error; - - if (error.Fail()) - { - switch (error.GetError()) - { - case EBADF: // One of the descriptor sets specified an invalid descriptor. - return eConnectionStatusLostConnection; - - case EINVAL: // The specified time limit is invalid. One of its components is negative or too large. - default: // Other unknown error - return eConnectionStatusError; - - case EAGAIN: // The kernel was (perhaps temporarily) unable to - // allocate the requested number of file descriptors, - // or we have non-blocking IO - case EINTR: // A signal was delivered before the time limit - // expired and before any of the selected events - // occurred. - break; // Lets keep reading to until we timeout - } - } - else if (num_set_fds == 0) - { - return eConnectionStatusTimedOut; - } - else if (num_set_fds > 0) - { - if (FD_ISSET(data_fd, &read_fds)) - return eConnectionStatusSuccess; - if (have_pipe_fd && FD_ISSET(pipe_fd, &read_fds)) - { - // We got a command to exit. Read the data from that pipe: - char buffer[16]; - ssize_t bytes_read; - - do - { - bytes_read = ::read (pipe_fd, buffer, sizeof(buffer)); - } while (bytes_read < 0 && errno == EINTR); - assert (bytes_read == 1 && buffer[0] == 'q'); - - if (log) - log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.", - this, (int) bytes_read, buffer); - - return eConnectionStatusEndOfFile; - } - } - } - } - - if (error_ptr) - error_ptr->SetErrorString("not connected"); - return eConnectionStatusLostConnection; -} - -#endif - -#if 0 -#include - -// This ConnectionFileDescriptor::BytesAvailable() uses poll(). poll() should NOT -// be used on MacOSX as it has all sorts of restrictions on the types of file descriptors -// that it doesn't support. -// -// There may be some systems that properly support poll() that could use this -// implementation. I will let each system opt into this on their own. -// -// PROS: -// - no restrictions on the fd value that is used -// CONS: -// - varies wildly from platform to platform in its implementation restrictions - -ConnectionStatus -ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_ptr) -{ - // Don't need to take the mutex here separately since we are only called from Read. If we - // ever get used more generally we will need to lock here as well. - - Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); - if (log) - log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", this, timeout_usec); - int timeout_msec = 0; - if (timeout_usec == UINT32_MAX) - { - // Infinite wait... - timeout_msec = -1; - } - else if (timeout_usec == 0) - { - // Return immediately, don't wait - timeout_msec = 0; - } - else - { - // Convert usec to msec - timeout_msec = (timeout_usec + 999) / 1000; - } - - // Make a copy of the file descriptors to make sure we don't - // have another thread change these values out from under us - // and cause problems in the loop below where like in FS_SET() - const int data_fd = m_fd_recv; - const int pipe_fd = m_pipe_read; - - // Make sure the file descriptor can be used with select as it - // must be in range - if (data_fd >= 0) - { - const bool have_pipe_fd = pipe_fd >= 0; - struct pollfd fds[2] = - { - { data_fd, POLLIN, 0 }, - { pipe_fd, POLLIN, 0 } - }; - const int nfds = have_pipe_fd ? 2 : 1; - Error error; - while (data_fd == m_fd_recv) - { - const int num_set_fds = ::poll (fds, nfds, timeout_msec); - - if (num_set_fds < 0) - error.SetErrorToErrno(); - else - error.Clear(); - - if (error_ptr) - *error_ptr = error; - - if (log) - { - if (have_pipe_fd) - log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::poll (fds={{%i,POLLIN},{%i,POLLIN}}, nfds=%i, timeout_ms=%i) => %d, error = %s\n", - this, - data_fd, - pipe_fd, - nfds, - timeout_msec, - num_set_fds, - error.AsCString()); - else - log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::poll (fds={{%i,POLLIN}}, nfds=%i, timeout_ms=%i) => %d, error = %s\n", - this, - data_fd, - nfds, - timeout_msec, - num_set_fds, - error.AsCString()); - } - - if (error.Fail()) - { - switch (error.GetError()) - { - case EBADF: // One of the descriptor sets specified an invalid descriptor. - return eConnectionStatusLostConnection; - - case EINVAL: // The specified time limit is invalid. One of its components is negative or too large. - default: // Other unknown error - return eConnectionStatusError; - - case EAGAIN: // The kernel was (perhaps temporarily) unable to - // allocate the requested number of file descriptors, - // or we have non-blocking IO - case EINTR: // A signal was delivered before the time limit - // expired and before any of the selected events - // occurred. - break; // Lets keep reading to until we timeout - } - } - else if (num_set_fds == 0) - { - return eConnectionStatusTimedOut; - } - else if (num_set_fds > 0) - { - if (fds[0].revents & POLLIN) - return eConnectionStatusSuccess; - if (fds[1].revents & POLLIN) - { - // We got a command to exit. Read the data from that pipe: - char buffer[16]; - ssize_t bytes_read; - - do - { - bytes_read = ::read (pipe_fd, buffer, sizeof(buffer)); - } while (bytes_read < 0 && errno == EINTR); - assert (bytes_read == 1 && buffer[0] == 'q'); - - if (log) - log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.", - this, (int) bytes_read, buffer); - - return eConnectionStatusEndOfFile; - } - } - } - } - if (error_ptr) - error_ptr->SetErrorString("not connected"); - return eConnectionStatusLostConnection; -} - -#endif - -ConnectionStatus -ConnectionFileDescriptor::Close (int& fd, FDType type, Error *error_ptr) -{ - if (error_ptr) - error_ptr->Clear(); - bool success = true; - // Avoid taking a lock if we can - if (fd >= 0) - { - Mutex::Locker locker (m_mutex); - // Check the FD after the lock is taken to ensure only one thread - // can get into the close scope below - if (fd >= 0) - { - Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); - if (log) - log->Printf ("%p ConnectionFileDescriptor::Close (fd = %i)", this,fd); -#if _WIN32 - if (type != eFDTypeFile) - success = closesocket(fd) == 0; - else -#endif - success = ::close (fd) == 0; - // A reference to a FD was passed in, set it to an invalid value - fd = -1; - if (!success && error_ptr) - { - // Only set the error if we have been asked to since something else - // might have caused us to try and shut down the connection and may - // have already set the error. - error_ptr->SetErrorToErrno(); - } - } - } - if (success) - return eConnectionStatusSuccess; - else - return eConnectionStatusError; -} + m_write_sp.reset(socket); + m_read_sp = m_write_sp; + return (error.Success()) ? eConnectionStatusSuccess : eConnectionStatusError; +} ConnectionStatus -ConnectionFileDescriptor::NamedSocketAccept (const char *socket_name, Error *error_ptr) -{ -#ifndef LLDB_DISABLE_POSIX - ConnectionStatus result = eConnectionStatusError; - struct sockaddr_un saddr_un; - - m_fd_send_type = m_fd_recv_type = eFDTypeSocket; - - int listen_socket = ::socket (AF_UNIX, SOCK_STREAM, 0); - if (listen_socket == -1) - { - if (error_ptr) - error_ptr->SetErrorToErrno(); - return eConnectionStatusError; - } - - saddr_un.sun_family = AF_UNIX; - ::strncpy(saddr_un.sun_path, socket_name, sizeof(saddr_un.sun_path) - 1); - saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0'; -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) - saddr_un.sun_len = SUN_LEN (&saddr_un); -#endif - - Host::Unlink (socket_name); - if (::bind (listen_socket, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) == 0) - { - if (::listen (listen_socket, 5) == 0) - { - m_fd_send = m_fd_recv = ::accept (listen_socket, NULL, 0); - if (m_fd_send > 0) - { - m_should_close_fd = true; - - if (error_ptr) - error_ptr->Clear(); - result = eConnectionStatusSuccess; - } - } - } - - if (result != eConnectionStatusSuccess) - { - if (error_ptr) - error_ptr->SetErrorToErrno(); - } - // We are done with the listen port - Close (listen_socket, eFDTypeSocket, NULL); - return result; -#else - return eConnectionStatusError; -#endif -} - -ConnectionStatus -ConnectionFileDescriptor::NamedSocketConnect (const char *socket_name, Error *error_ptr) +ConnectionFileDescriptor::ConnectTCP(const char *s, Error *error_ptr) { -#ifndef LLDB_DISABLE_POSIX - Disconnect (NULL); - m_fd_send_type = m_fd_recv_type = eFDTypeSocket; - - // Open the socket that was passed in as an option - struct sockaddr_un saddr_un; - m_fd_send = m_fd_recv = ::socket (AF_UNIX, SOCK_STREAM, 0); - if (m_fd_send == -1) - { - if (error_ptr) - error_ptr->SetErrorToErrno(); - return eConnectionStatusError; - } - - saddr_un.sun_family = AF_UNIX; - ::strncpy(saddr_un.sun_path, socket_name, sizeof(saddr_un.sun_path) - 1); - saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0'; -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) - saddr_un.sun_len = SUN_LEN (&saddr_un); -#endif - - if (::connect (m_fd_send, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0) - { - if (error_ptr) - error_ptr->SetErrorToErrno(); - Disconnect (NULL); - return eConnectionStatusError; - } + Socket* socket = nullptr; + Error error = Socket::TcpConnect(s, socket); if (error_ptr) - error_ptr->Clear(); - return eConnectionStatusSuccess; -#else - return eConnectionStatusError; -#endif -} - -ConnectionStatus -ConnectionFileDescriptor::SocketListen (const char *host_and_port, Error *error_ptr) -{ - Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); - if (log) - log->Printf ("%p ConnectionFileDescriptor::SocketListen (%s)", this, host_and_port); - - Disconnect (NULL); - m_fd_send_type = m_fd_recv_type = eFDTypeSocket; - std::string host_str; - std::string port_str; - int32_t port = INT32_MIN; - if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr)) - { - // Might be just a port number - port = Args::StringToSInt32(host_and_port, -1); - if (port == -1) - return eConnectionStatusError; - else - host_str.clear(); - } - const sa_family_t family = AF_INET; - const int socktype = SOCK_STREAM; - const int protocol = IPPROTO_TCP; - int listen_fd = ::socket (family, socktype, protocol); - if (listen_fd == -1) - { - if (error_ptr) - error_ptr->SetErrorToErrno(); - return eConnectionStatusError; - } - - // enable local address reuse - SetSocketOption (listen_fd, SOL_SOCKET, SO_REUSEADDR, 1); - - SocketAddress listen_addr; - if (host_str.empty()) - listen_addr.SetToLocalhost(family, port); - else if (host_str.compare("*") == 0) - listen_addr.SetToAnyAddress(family, port); - else - { - if (!listen_addr.getaddrinfo(host_str.c_str(), port_str.c_str(), family, socktype, protocol)) - { - if (error_ptr) - error_ptr->SetErrorStringWithFormat("unable to resolve hostname '%s'", host_str.c_str()); - Close (listen_fd, eFDTypeSocket, NULL); - return eConnectionStatusError; - } - } - - SocketAddress anyaddr; - if (anyaddr.SetToAnyAddress (family, port)) - { - int err = ::bind (listen_fd, anyaddr, anyaddr.GetLength()); - if (err == -1) - { - if (error_ptr) - error_ptr->SetErrorToErrno(); - Close (listen_fd, eFDTypeSocket, NULL); - return eConnectionStatusError; - } - - err = ::listen (listen_fd, 1); - if (err == -1) - { - if (error_ptr) - error_ptr->SetErrorToErrno(); - Close (listen_fd, eFDTypeSocket, NULL); - return eConnectionStatusError; - } - - // We were asked to listen on port zero which means we - // must now read the actual port that was given to us - // as port zero is a special code for "find an open port - // for me". - if (port == 0) - port = GetSocketPort(listen_fd); - - // Set the port predicate since when doing a listen://: - // it often needs to accept the incoming connection which is a blocking - // system call. Allowing access to the bound port using a predicate allows - // us to wait for the port predicate to be set to a non-zero value from - // another thread in an efficient manor. - m_port_predicate.SetValue(port, eBroadcastAlways); - - - bool accept_connection = false; - - // Loop until we are happy with our connection - while (!accept_connection) - { - struct sockaddr_in accept_addr; - ::memset (&accept_addr, 0, sizeof accept_addr); -#if !(defined (__linux__) || defined(_MSC_VER)) - accept_addr.sin_len = sizeof accept_addr; -#endif - socklen_t accept_addr_len = sizeof accept_addr; - - int fd = ::accept (listen_fd, (struct sockaddr *)&accept_addr, &accept_addr_len); - - if (fd == -1) - { - if (error_ptr) - error_ptr->SetErrorToErrno(); - break; - } - - if (listen_addr.sockaddr_in().sin_addr.s_addr == INADDR_ANY) - { - accept_connection = true; - m_fd_send = m_fd_recv = fd; - } - else - { - if ( -#if !(defined(__linux__) || (defined(_MSC_VER))) - accept_addr_len == listen_addr.sockaddr_in().sin_len && -#endif - accept_addr.sin_addr.s_addr == listen_addr.sockaddr_in().sin_addr.s_addr) - { - accept_connection = true; - m_fd_send = m_fd_recv = fd; - } - else - { - ::close (fd); - m_fd_send = m_fd_recv = -1; - const uint8_t *accept_ip = (const uint8_t *)&accept_addr.sin_addr.s_addr; - const uint8_t *listen_ip = (const uint8_t *)&listen_addr.sockaddr_in().sin_addr.s_addr; - ::fprintf (stderr, "error: rejecting incoming connection from %u.%u.%u.%u (expecting %u.%u.%u.%u)\n", - accept_ip[0], accept_ip[1], accept_ip[2], accept_ip[3], - listen_ip[0], listen_ip[1], listen_ip[2], listen_ip[3]); - } - } - } - - if (m_fd_send == -1) - { - Close (listen_fd, eFDTypeSocket, NULL); - return eConnectionStatusError; - } - } - - // We are done with the listen port - Close (listen_fd, eFDTypeSocket, NULL); - - m_should_close_fd = true; - - // Keep our TCP packets coming without any delays. - SetSocketOption (m_fd_send, IPPROTO_TCP, TCP_NODELAY, 1); - if (error_ptr) - error_ptr->Clear(); - return eConnectionStatusSuccess; -} - -ConnectionStatus -ConnectionFileDescriptor::ConnectTCP (const char *host_and_port, Error *error_ptr) -{ - Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); - if (log) - log->Printf ("%p ConnectionFileDescriptor::ConnectTCP (host/port = %s)", this, host_and_port); - Disconnect (NULL); - - m_fd_send_type = m_fd_recv_type = eFDTypeSocket; - std::string host_str; - std::string port_str; - int32_t port = INT32_MIN; - if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr)) - return eConnectionStatusError; - - // Create the socket - m_fd_send = m_fd_recv = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (m_fd_send == -1) - { - if (error_ptr) - error_ptr->SetErrorToErrno(); - return eConnectionStatusError; - } - - m_should_close_fd = true; - - // Enable local address reuse - SetSocketOption (m_fd_send, SOL_SOCKET, SO_REUSEADDR, 1); - - struct sockaddr_in sa; - ::memset (&sa, 0, sizeof (sa)); - sa.sin_family = AF_INET; - sa.sin_port = htons (port); - - int inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr); - - if (inet_pton_result <= 0) - { - struct hostent *host_entry = gethostbyname (host_str.c_str()); - if (host_entry) - host_str = ::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list); - inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr); - if (inet_pton_result <= 0) - { - - if (error_ptr) - { - if (inet_pton_result == -1) - error_ptr->SetErrorToErrno(); - else - error_ptr->SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str()); - } - Disconnect (NULL); - - return eConnectionStatusError; - } - } - - if (-1 == ::connect (m_fd_send, (const struct sockaddr *)&sa, sizeof(sa))) - { - if (error_ptr) - error_ptr->SetErrorToErrno(); - Disconnect (NULL); - - return eConnectionStatusError; - } - - // Keep our TCP packets coming without any delays. - SetSocketOption (m_fd_send, IPPROTO_TCP, TCP_NODELAY, 1); - if (error_ptr) - error_ptr->Clear(); - return eConnectionStatusSuccess; + *error_ptr = error; + m_write_sp.reset(socket); + m_read_sp = m_write_sp; + return (error.Success()) ? eConnectionStatusSuccess : eConnectionStatusError; } ConnectionStatus -ConnectionFileDescriptor::ConnectUDP (const char *host_and_port, Error *error_ptr) +ConnectionFileDescriptor::ConnectUDP(const char *s, Error *error_ptr) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); - if (log) - log->Printf ("%p ConnectionFileDescriptor::ConnectUDP (host/port = %s)", this, host_and_port); - Disconnect (NULL); - - m_fd_send_type = m_fd_recv_type = eFDTypeSocketUDP; - - std::string host_str; - std::string port_str; - int32_t port = INT32_MIN; - if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr)) - return eConnectionStatusError; - - // Setup the receiving end of the UDP connection on this localhost - // on port zero. After we bind to port zero we can read the port. - m_fd_recv = ::socket (AF_INET, SOCK_DGRAM, 0); - if (m_fd_recv == -1) - { - // Socket creation failed... - if (error_ptr) - error_ptr->SetErrorToErrno(); - } - else - { - // Socket was created, now lets bind to the requested port - SocketAddress addr; - addr.SetToAnyAddress (AF_INET, 0); - - if (::bind (m_fd_recv, addr, addr.GetLength()) == -1) - { - // Bind failed... - if (error_ptr) - error_ptr->SetErrorToErrno(); - Disconnect (NULL); - } - } - - if (m_fd_recv == -1) - return eConnectionStatusError; - - // At this point we have setup the recieve port, now we need to - // setup the UDP send socket - - struct addrinfo hints; - struct addrinfo *service_info_list = NULL; - - ::memset (&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_DGRAM; - int err = ::getaddrinfo (host_str.c_str(), port_str.c_str(), &hints, &service_info_list); - if (err != 0) - { - if (error_ptr) - error_ptr->SetErrorStringWithFormat("getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)", - host_str.c_str(), - port_str.c_str(), - err, - gai_strerror(err)); - Disconnect (NULL); - return eConnectionStatusError; - } - - for (struct addrinfo *service_info_ptr = service_info_list; - service_info_ptr != NULL; - service_info_ptr = service_info_ptr->ai_next) - { - m_fd_send = ::socket (service_info_ptr->ai_family, - service_info_ptr->ai_socktype, - service_info_ptr->ai_protocol); - - if (m_fd_send != -1) - { - *m_udp_send_sockaddr = service_info_ptr; - break; - } - else - continue; - } - - :: freeaddrinfo (service_info_list); - - if (m_fd_send == -1) - { - Disconnect (NULL); - return eConnectionStatusError; - } - + Socket* send_socket = nullptr; + Socket* recv_socket = nullptr; + Error error = Socket::UdpConnect(s, send_socket, recv_socket); if (error_ptr) - error_ptr->Clear(); - - m_should_close_fd = true; - return eConnectionStatusSuccess; -} - -#if defined(_WIN32) -typedef const char * set_socket_option_arg_type; -typedef char * get_socket_option_arg_type; -#else // #if defined(_WIN32) -typedef const void * set_socket_option_arg_type; -typedef void * get_socket_option_arg_type; -#endif // #if defined(_WIN32) - -int -ConnectionFileDescriptor::GetSocketOption(int fd, int level, int option_name, int &option_value) -{ - get_socket_option_arg_type option_value_p = reinterpret_cast(&option_value); - socklen_t option_value_size = sizeof(int); - return ::getsockopt(fd, level, option_name, option_value_p, &option_value_size); -} - -int -ConnectionFileDescriptor::SetSocketOption(int fd, int level, int option_name, int option_value) -{ - set_socket_option_arg_type option_value_p = reinterpret_cast(&option_value); - return ::setsockopt(fd, level, option_name, option_value_p, sizeof(option_value)); -} - -bool -ConnectionFileDescriptor::SetSocketReceiveTimeout (uint32_t timeout_usec) -{ - switch (m_fd_recv_type) - { - case eFDTypeFile: // Other FD requireing read/write - break; - - case eFDTypeSocket: // Socket requiring send/recv - case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom - { - // Check in case timeout for m_fd has already been set to this value - if (timeout_usec == m_socket_timeout_usec) - return true; - //printf ("ConnectionFileDescriptor::SetSocketReceiveTimeout (timeout_usec = %u)\n", timeout_usec); - - struct timeval timeout; - if (timeout_usec == UINT32_MAX) - { - timeout.tv_sec = 0; - timeout.tv_usec = 0; - } - else if (timeout_usec == 0) - { - // Sending in zero does an infinite timeout, so set this as low - // as we can go to get an effective zero timeout... - timeout.tv_sec = 0; - timeout.tv_usec = 1; - } - else - { - timeout.tv_sec = timeout_usec / TimeValue::MicroSecPerSec; - timeout.tv_usec = timeout_usec % TimeValue::MicroSecPerSec; - } - if (::setsockopt (m_fd_recv, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast(&timeout), sizeof(timeout)) == 0) - { - m_socket_timeout_usec = timeout_usec; - return true; - } - } - } - return false; -} - -uint16_t -ConnectionFileDescriptor::GetSocketPort (int fd) -{ - // We bound to port zero, so we need to figure out which port we actually bound to - if (fd >= 0) - { - SocketAddress sock_addr; - socklen_t sock_addr_len = sock_addr.GetMaxLength (); - if (::getsockname (fd, sock_addr, &sock_addr_len) == 0) - return sock_addr.GetPort (); - } - return 0; -} - -// If the read file descriptor is a socket, then return -// the port number that is being used by the socket. -uint16_t -ConnectionFileDescriptor::GetReadPort () const -{ - return ConnectionFileDescriptor::GetSocketPort (m_fd_recv); + *error_ptr = error; + m_write_sp.reset(send_socket); + m_read_sp.reset(recv_socket); + return (error.Success()) ? eConnectionStatusSuccess : eConnectionStatusError; } -// If the write file descriptor is a socket, then return -// the port number that is being used by the socket. -uint16_t -ConnectionFileDescriptor::GetWritePort () const -{ - return ConnectionFileDescriptor::GetSocketPort (m_fd_send); -} -uint16_t -ConnectionFileDescriptor::GetBoundPort (uint32_t timeout_sec) +uint16_t ConnectionFileDescriptor::GetListeningPort(uint32_t timeout_sec) { uint16_t bound_port = 0; if (timeout_sec == UINT32_MAX) diff --git a/source/Core/ConnectionMachPort.cpp b/source/Core/ConnectionMachPort.cpp index 4a090dbe5ec8..05ada9872b5b 100644 --- a/source/Core/ConnectionMachPort.cpp +++ b/source/Core/ConnectionMachPort.cpp @@ -127,7 +127,7 @@ ConnectionMachPort::BootstrapCheckIn (const char *port, Error *error_ptr) { name_t port_name; int len = snprintf(port_name, sizeof(port_name), "%s", port); - if (len < sizeof(port_name)) + if (static_cast(len) < sizeof(port_name)) { kret = ::bootstrap_check_in (bootstrap_port, port_name, @@ -160,7 +160,7 @@ ConnectionMachPort::BootstrapLookup (const char *port, if (port && port[0]) { - if (::snprintf (port_name, sizeof (port_name), "%s", port) >= sizeof (port_name)) + if (static_cast(::snprintf (port_name, sizeof (port_name), "%s", port)) >= sizeof (port_name)) { if (error_ptr) error_ptr->SetErrorString ("port netname is too long"); diff --git a/source/Core/ConnectionSharedMemory.cpp b/source/Core/ConnectionSharedMemory.cpp index cd708c4868c9..5db3d687cdb2 100644 --- a/source/Core/ConnectionSharedMemory.cpp +++ b/source/Core/ConnectionSharedMemory.cpp @@ -24,6 +24,7 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include "llvm/Support/MathExtras.h" #include "lldb/lldb-private-log.h" #include "lldb/Core/Communication.h" #include "lldb/Core/Log.h" @@ -125,8 +126,15 @@ ConnectionSharedMemory::Open (bool create, const char *name, size_t size, Error #ifdef _WIN32 HANDLE handle; - if (create) - handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, (DWORD)(size >> 32), (DWORD)(size), name); + if (create) { + handle = CreateFileMapping( + INVALID_HANDLE_VALUE, + NULL, + PAGE_READWRITE, + llvm::Hi_32(size), + llvm::Lo_32(size), + name); + } else handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, name); diff --git a/source/Core/ConstString.cpp b/source/Core/ConstString.cpp index ce6e51108db5..5657b483a495 100644 --- a/source/Core/ConstString.cpp +++ b/source/Core/ConstString.cpp @@ -294,7 +294,10 @@ ConstString::DumpDebug(Stream *s) const size_t cstr_len = GetLength(); // Only print the parens if we have a non-NULL string const char *parens = cstr ? "\"" : ""; - s->Printf("%*p: ConstString, string = %s%s%s, length = %" PRIu64, (int)sizeof(void*) * 2, this, parens, cstr, parens, (uint64_t)cstr_len); + s->Printf("%*p: ConstString, string = %s%s%s, length = %" PRIu64, + static_cast(sizeof(void*) * 2), + static_cast(this), parens, cstr, parens, + static_cast(cstr_len)); } void diff --git a/source/Core/DataBufferHeap.cpp b/source/Core/DataBufferHeap.cpp index 2c8a865b966c..984b36e54153 100644 --- a/source/Core/DataBufferHeap.cpp +++ b/source/Core/DataBufferHeap.cpp @@ -103,6 +103,12 @@ DataBufferHeap::CopyData (const void *src, uint64_t src_len) m_data.clear(); } +void +DataBufferHeap::AppendData (const void *src, uint64_t src_len) +{ + m_data.insert(m_data.end(), (uint8_t *)src, (uint8_t *)src + src_len); +} + void DataBufferHeap::Clear() { diff --git a/source/Core/DataBufferMemoryMap.cpp b/source/Core/DataBufferMemoryMap.cpp index 008b736ef726..4ca43b89eef1 100644 --- a/source/Core/DataBufferMemoryMap.cpp +++ b/source/Core/DataBufferMemoryMap.cpp @@ -18,11 +18,13 @@ #include #endif +#include "llvm/Support/MathExtras.h" + #include "lldb/Core/DataBufferMemoryMap.h" #include "lldb/Core/Error.h" #include "lldb/Host/File.h" #include "lldb/Host/FileSpec.h" -#include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Core/Log.h" #include "lldb/lldb-private-log.h" @@ -89,7 +91,7 @@ DataBufferMemoryMap::Clear() { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP)); if (log) - log->Printf("DataBufferMemoryMap::Clear() m_mmap_addr = %p, m_mmap_size = %zu", m_mmap_addr, m_mmap_size); + log->Printf("DataBufferMemoryMap::Clear() m_mmap_addr = %p, m_mmap_size = %" PRIu64 "", m_mmap_addr, (uint64_t)m_mmap_size); #ifdef _WIN32 UnmapViewOfFile(m_mmap_addr); #else @@ -113,7 +115,7 @@ DataBufferMemoryMap::Clear() size_t DataBufferMemoryMap::MemoryMapFromFileSpec (const FileSpec* filespec, lldb::offset_t offset, - lldb::offset_t length, + size_t length, bool writeable) { if (filespec != NULL) @@ -124,7 +126,7 @@ DataBufferMemoryMap::MemoryMapFromFileSpec (const FileSpec* filespec, log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec(file=\"%s\", offset=0x%" PRIx64 ", length=0x%" PRIx64 ", writeable=%i", filespec->GetPath().c_str(), offset, - length, + (uint64_t)length, writeable); } char path[PATH_MAX]; @@ -147,16 +149,16 @@ DataBufferMemoryMap::MemoryMapFromFileSpec (const FileSpec* filespec, Clear(); return 0; } - - -#ifdef _WIN32 -static size_t win32memmapalignment = 0; -void LoadWin32MemMapAlignment () -{ - SYSTEM_INFO data; - GetSystemInfo(&data); - win32memmapalignment = data.dwAllocationGranularity; -} + + +#ifdef _WIN32 +static size_t win32memmapalignment = 0; +void LoadWin32MemMapAlignment () +{ + SYSTEM_INFO data; + GetSystemInfo(&data); + win32memmapalignment = data.dwAllocationGranularity; +} #endif //---------------------------------------------------------------------- @@ -174,7 +176,7 @@ void LoadWin32MemMapAlignment () size_t DataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd, lldb::offset_t offset, - lldb::offset_t length, + size_t length, bool writeable, bool fd_is_file) { @@ -184,14 +186,10 @@ DataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd, Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP|LIBLLDB_LOG_VERBOSE)); if (log) { -#ifdef _WIN32 - log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec(fd=%p, offset=0x%" PRIx64 ", length=0x%" PRIx64 ", writeable=%i, fd_is_file=%i)", -#else - log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec(fd=%i, offset=0x%" PRIx64 ", length=0x%" PRIx64 ", writeable=%i, fd_is_file=%i)", -#endif + log->Printf("DataBufferMemoryMap::MemoryMapFromFileDescriptor(fd=%i, offset=0x%" PRIx64 ", length=0x%" PRIx64 ", writeable=%i, fd_is_file=%i)", fd, offset, - length, + (uint64_t)length, writeable, fd_is_file); } @@ -199,16 +197,13 @@ DataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd, HANDLE handle = (HANDLE)_get_osfhandle(fd); DWORD file_size_low, file_size_high; file_size_low = GetFileSize(handle, &file_size_high); - const size_t file_size = (file_size_high << 32) | file_size_low; - const size_t max_bytes_available = file_size - offset; - if (length == SIZE_MAX) - { - length = max_bytes_available; - } - else if (length > max_bytes_available) + const lldb::offset_t file_size = llvm::Make_64(file_size_high, file_size_low); + const lldb::offset_t max_bytes_available = file_size - offset; + const size_t max_bytes_mappable = (size_t)std::min(SIZE_MAX, max_bytes_available); + if (length == SIZE_MAX || length > max_bytes_mappable) { // Cap the length if too much data was requested - length = max_bytes_available; + length = max_bytes_mappable; } if (length > 0) @@ -216,23 +211,23 @@ DataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd, HANDLE fileMapping = CreateFileMapping(handle, NULL, writeable ? PAGE_READWRITE : PAGE_READONLY, file_size_high, file_size_low, NULL); if (fileMapping != NULL) { - if (win32memmapalignment == 0) LoadWin32MemMapAlignment(); - lldb::offset_t realoffset = offset; - lldb::offset_t delta = 0; - if (realoffset % win32memmapalignment != 0) { - realoffset = realoffset / win32memmapalignment * win32memmapalignment; - delta = offset - realoffset; - } - - LPVOID data = MapViewOfFile(fileMapping, writeable ? FILE_MAP_WRITE : FILE_MAP_READ, 0, realoffset, length + delta); - m_mmap_addr = (uint8_t *)data; - if (!data) { - Error error; - error.SetErrorToErrno (); + if (win32memmapalignment == 0) LoadWin32MemMapAlignment(); + lldb::offset_t realoffset = offset; + lldb::offset_t delta = 0; + if (realoffset % win32memmapalignment != 0) { + realoffset = realoffset / win32memmapalignment * win32memmapalignment; + delta = offset - realoffset; + } + + LPVOID data = MapViewOfFile(fileMapping, writeable ? FILE_MAP_WRITE : FILE_MAP_READ, 0, realoffset, length + delta); + m_mmap_addr = (uint8_t *)data; + if (!data) { + Error error; + error.SetErrorToErrno (); } else { - m_data = m_mmap_addr + delta; - m_size = length; - } + m_data = m_mmap_addr + delta; + m_size = length; + } CloseHandle(fileMapping); } } @@ -240,7 +235,8 @@ DataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd, struct stat stat; if (::fstat(fd, &stat) == 0) { - if (S_ISREG(stat.st_mode) && (stat.st_size > offset)) + if (S_ISREG(stat.st_mode) && + (stat.st_size > static_cast(offset))) { const size_t max_bytes_available = stat.st_size - offset; if (length == SIZE_MAX) @@ -272,7 +268,7 @@ DataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd, if (error.GetError() == EINVAL) { // We may still have a shot at memory mapping if we align things correctly - size_t page_offset = offset % Host::GetPageSize(); + size_t page_offset = offset % HostInfo::GetPageSize(); if (page_offset != 0) { m_mmap_addr = (uint8_t *)::mmap(NULL, length + page_offset, prot, flags, fd, offset - page_offset); @@ -311,8 +307,8 @@ DataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd, if (log) { - log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec() m_mmap_addr = %p, m_mmap_size = %zu, error = %s", - m_mmap_addr, m_mmap_size, error.AsCString()); + log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec() m_mmap_addr = %p, m_mmap_size = %" PRIu64 ", error = %s", + m_mmap_addr, (uint64_t)m_mmap_size, error.AsCString()); } } } diff --git a/source/Core/DataExtractor.cpp b/source/Core/DataExtractor.cpp index b42c6ff31449..a0958bd6b1c6 100644 --- a/source/Core/DataExtractor.cpp +++ b/source/Core/DataExtractor.cpp @@ -52,7 +52,7 @@ ReadInt16(const unsigned char* ptr, offset_t offset) } static inline uint32_t -ReadInt32 (const unsigned char* ptr, offset_t offset) +ReadInt32 (const unsigned char* ptr, offset_t offset = 0) { uint32_t value; memcpy (&value, ptr + offset, 4); @@ -60,7 +60,7 @@ ReadInt32 (const unsigned char* ptr, offset_t offset) } static inline uint64_t -ReadInt64(const unsigned char* ptr, offset_t offset) +ReadInt64(const unsigned char* ptr, offset_t offset = 0) { uint64_t value; memcpy (&value, ptr + offset, 8); @@ -75,22 +75,6 @@ ReadInt16(const void* ptr) return value; } -static inline uint32_t -ReadInt32 (const void* ptr) -{ - uint32_t value; - memcpy (&value, ptr, 4); - return value; -} - -static inline uint64_t -ReadInt64(const void* ptr) -{ - uint64_t value; - memcpy (&value, ptr, 8); - return value; -} - static inline uint16_t ReadSwapInt16(const unsigned char* ptr, offset_t offset) { @@ -409,7 +393,7 @@ DataExtractor::GetU8 (offset_t *offset_ptr) const // // RETURNS the non-NULL buffer pointer upon successful extraction of // all the requested bytes, or NULL when the data is not available in -// the buffer due to being out of bounds, or unsufficient data. +// the buffer due to being out of bounds, or insufficient data. //---------------------------------------------------------------------- void * DataExtractor::GetU8 (offset_t *offset_ptr, void *dst, uint32_t count) const @@ -490,7 +474,7 @@ DataExtractor::GetU64_unchecked (offset_t *offset_ptr) const // // RETURNS the non-NULL buffer pointer upon successful extraction of // all the requested bytes, or NULL when the data is not available -// in the buffer due to being out of bounds, or unsufficient data. +// in the buffer due to being out of bounds, or insufficient data. //---------------------------------------------------------------------- void * DataExtractor::GetU16 (offset_t *offset_ptr, void *void_dst, uint32_t count) const @@ -553,7 +537,7 @@ DataExtractor::GetU32 (offset_t *offset_ptr) const // // RETURNS the non-NULL buffer pointer upon successful extraction of // all the requested bytes, or NULL when the data is not available -// in the buffer due to being out of bounds, or unsufficient data. +// in the buffer due to being out of bounds, or insufficient data. //---------------------------------------------------------------------- void * DataExtractor::GetU32 (offset_t *offset_ptr, void *void_dst, uint32_t count) const @@ -1124,7 +1108,7 @@ DataExtractor::CopyByteOrderedData (offset_t src_offset, // follows the NULL terminator byte. // // If the offset pointed to by "offset_ptr" is out of bounds, or if -// "length" is non-zero and there aren't enough avaialable +// "length" is non-zero and there aren't enough available // bytes, NULL will be returned and "offset_ptr" will not be // updated. //---------------------------------------------------------------------- @@ -1150,7 +1134,7 @@ DataExtractor::GetCStr (offset_t *offset_ptr) const // We reached the end of the data without finding a NULL C string // terminator. Fall through and return NULL otherwise anyone that - // would have used the result as a C string can wonder into + // would have used the result as a C string can wander into // unknown memory... } return NULL; @@ -1491,7 +1475,7 @@ DataExtractor::Dump (Stream *s, if (item_format == eFormatBytesWithASCII && offset > line_start_offset) { s->Printf("%*s", static_cast((num_per_line - (offset - line_start_offset)) * 3 + 2), ""); - Dump(s, line_start_offset, eFormatCharPrintable, 1, offset - line_start_offset, LLDB_INVALID_OFFSET, LLDB_INVALID_ADDRESS, 0, 0); + Dump(s, line_start_offset, eFormatCharPrintable, 1, offset - line_start_offset, SIZE_MAX, LLDB_INVALID_ADDRESS, 0, 0); } s->EOL(); } @@ -1516,7 +1500,7 @@ DataExtractor::Dump (Stream *s, s->Printf ("%s", GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset) ? "true" : "false"); else { - s->Printf("error: unsupported byte size (%zu) for boolean format", item_byte_size); + s->Printf("error: unsupported byte size (%" PRIu64 ") for boolean format", (uint64_t)item_byte_size); return offset; } break; @@ -1725,7 +1709,7 @@ DataExtractor::Dump (Stream *s, } else { - s->Printf("error: unsupported byte size (%zu) for complex integer format", item_byte_size); + s->Printf("error: unsupported byte size (%" PRIu64 ") for complex integer format", (uint64_t)item_byte_size); return offset; } } @@ -1757,7 +1741,7 @@ DataExtractor::Dump (Stream *s, } else { - s->Printf("error: unsupported byte size (%zu) for complex float format", item_byte_size); + s->Printf("error: unsupported byte size (%" PRIu64 ") for complex float format", (uint64_t)item_byte_size); return offset; } break; @@ -1839,14 +1823,11 @@ DataExtractor::Dump (Stream *s, else if (item_bit_size == ast->getTypeSize(ast->LongDoubleTy)) { llvm::APInt apint; - switch (target_sp->GetArchitecture().GetCore()) + switch (target_sp->GetArchitecture().GetMachine()) { - case ArchSpec::eCore_x86_32_i386: - case ArchSpec::eCore_x86_32_i486: - case ArchSpec::eCore_x86_32_i486sx: - case ArchSpec::eCore_x86_64_x86_64: - case ArchSpec::eCore_x86_64_x86_64h: - // clang will assert when contructing the apfloat if we use a 16 byte integer value + case llvm::Triple::x86: + case llvm::Triple::x86_64: + // clang will assert when constructing the apfloat if we use a 16 byte integer value if (GetAPInt (*this, &offset, 10, apint)) { llvm::APFloat apfloat (ast->getFloatTypeSemantics(ast->LongDoubleTy), apint); @@ -1909,7 +1890,7 @@ DataExtractor::Dump (Stream *s, } else { - s->Printf("error: unsupported byte size (%zu) for float format", item_byte_size); + s->Printf("error: unsupported byte size (%" PRIu64 ") for float format", (uint64_t)item_byte_size); return offset; } ss.flush(); @@ -1973,7 +1954,7 @@ DataExtractor::Dump (Stream *s, } else { - s->Printf("error: unsupported byte size (%zu) for hex float format", item_byte_size); + s->Printf("error: unsupported byte size (%" PRIu64 ") for hex float format", (uint64_t)item_byte_size); return offset; } break; @@ -2058,7 +2039,7 @@ DataExtractor::Dump (Stream *s, if (item_format == eFormatBytesWithASCII && offset > line_start_offset) { s->Printf("%*s", static_cast((num_per_line - (offset - line_start_offset)) * 3 + 2), ""); - Dump(s, line_start_offset, eFormatCharPrintable, 1, offset - line_start_offset, LLDB_INVALID_OFFSET, LLDB_INVALID_ADDRESS, 0, 0); + Dump(s, line_start_offset, eFormatCharPrintable, 1, offset - line_start_offset, SIZE_MAX, LLDB_INVALID_ADDRESS, 0, 0); } return offset; // Return the offset at which we ended up } diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp index 34e0e329f092..178296347677 100644 --- a/source/Core/Debugger.cpp +++ b/source/Core/Debugger.cpp @@ -15,6 +15,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/Type.h" +#include "llvm/ADT/StringRef.h" #include "lldb/lldb-private.h" #include "lldb/Core/ConnectionFileDescriptor.h" @@ -26,12 +27,14 @@ #include "lldb/Core/StreamCallback.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/StreamString.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Core/Timer.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/DataFormatters/DataVisualization.h" #include "lldb/DataFormatters/FormatManager.h" -#include "lldb/Host/DynamicLibrary.h" +#include "lldb/DataFormatters/TypeSummary.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Host/Terminal.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/OptionValueSInt64.h" @@ -50,6 +53,8 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/AnsiTerminal.h" +#include "llvm/Support/DynamicLibrary.h" + using namespace lldb; using namespace lldb_private; @@ -72,7 +77,7 @@ static DebuggerList & GetDebuggerList() { // hide the static debugger list inside a singleton accessor to avoid - // global init contructors + // global init constructors static DebuggerList g_list; return g_list; } @@ -104,8 +109,11 @@ g_language_enumerators[] = FILE_AND_LINE\ "{, name = '${thread.name}'}"\ "{, queue = '${thread.queue}'}"\ + "{, activity = '${thread.info.activity.name}'}" \ + "{, ${thread.info.trace_messages} messages}" \ "{, stop reason = ${thread.stop-reason}}"\ "{\\nReturn value: ${thread.return-value}}"\ + "{\\nCompleted expression: ${thread.completed-expression}}"\ "\\n" #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\ @@ -406,10 +414,10 @@ Debugger::LoadPlugin (const FileSpec& spec, Error& error) { if (g_load_plugin_callback) { - lldb::DynamicLibrarySP dynlib_sp = g_load_plugin_callback (shared_from_this(), spec, error); - if (dynlib_sp) + llvm::sys::DynamicLibrary dynlib = g_load_plugin_callback (shared_from_this(), spec, error); + if (dynlib.isValid()) { - m_loaded_plugins.push_back(dynlib_sp); + m_loaded_plugins.push_back(dynlib); return true; } } @@ -470,7 +478,7 @@ LoadPluginCallback { // Try and recurse into anything that a directory or symbolic link. // We must also do this for unknown as sometimes the directory enumeration - // might be enurating a file system that doesn't have correct file type + // might be enumerating a file system that doesn't have correct file type // information. return FileSpec::eEnumerateDirectoryResultEnter; } @@ -486,7 +494,7 @@ Debugger::InstanceInitialize () const bool find_files = true; const bool find_other = true; char dir_path[PATH_MAX]; - if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec)) + if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec)) { if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) { @@ -498,8 +506,8 @@ Debugger::InstanceInitialize () this); } } - - if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec)) + + if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec)) { if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) { @@ -629,8 +637,7 @@ Debugger::Debugger (lldb::LogOutputCallback log_callback, void *baton) : m_instance_name (), m_loaded_plugins (), m_event_handler_thread (LLDB_INVALID_HOST_THREAD), - m_io_handler_thread (LLDB_INVALID_HOST_THREAD), - m_event_handler_thread_alive(false) + m_io_handler_thread (LLDB_INVALID_HOST_THREAD) { char instance_cstr[256]; snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID()); @@ -696,6 +703,8 @@ Debugger::Clear() m_terminal_state.Clear(); if (m_input_file_sp) m_input_file_sp->GetFile().Close (); + + m_command_interpreter_ap->Clear(); } bool @@ -896,9 +905,29 @@ Debugger::RunIOHandler (const IOHandlerSP& reader_sp) { Mutex::Locker locker (m_input_reader_stack.GetMutex()); PushIOHandler (reader_sp); - reader_sp->Activate(); - reader_sp->Run(); - PopIOHandler (reader_sp); + + IOHandlerSP top_reader_sp = reader_sp; + while (top_reader_sp) + { + top_reader_sp->Activate(); + top_reader_sp->Run(); + top_reader_sp->Deactivate(); + + if (top_reader_sp.get() == reader_sp.get()) + { + if (PopIOHandler (reader_sp)) + break; + } + + while (1) + { + top_reader_sp = m_input_reader_stack.Top(); + if (top_reader_sp && top_reader_sp->GetIsDone()) + m_input_reader_stack.Pop(); + else + break; + } + } } void @@ -960,13 +989,17 @@ Debugger::PushIOHandler (const IOHandlerSP& reader_sp) // Got the current top input reader... IOHandlerSP top_reader_sp (m_input_reader_stack.Top()); - // Push our new input reader - m_input_reader_stack.Push (reader_sp); + // Don't push the same IO handler twice... + if (reader_sp.get() != top_reader_sp.get()) + { + // Push our new input reader + m_input_reader_stack.Push (reader_sp); - // Interrupt the top input reader to it will exit its Run() function - // and let this new input reader take over - if (top_reader_sp) - top_reader_sp->Deactivate(); + // Interrupt the top input reader to it will exit its Run() function + // and let this new input reader take over + if (top_reader_sp) + top_reader_sp->Deactivate(); + } } bool @@ -977,7 +1010,7 @@ Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp) Mutex::Locker locker (m_input_reader_stack.GetMutex()); // The reader on the stop of the stack is done, so let the next - // read on the stack referesh its prompt and if there is one... + // read on the stack refresh its prompt and if there is one... if (!m_input_reader_stack.IsEmpty()) { IOHandlerSP reader_sp(m_input_reader_stack.Top()); @@ -985,6 +1018,7 @@ Debugger::PopIOHandler (const IOHandlerSP& pop_reader_sp) if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get()) { reader_sp->Deactivate(); + reader_sp->Cancel(); m_input_reader_stack.Pop (); reader_sp = m_input_reader_stack.Top(); @@ -1085,6 +1119,7 @@ Debugger::FindDebuggerWithID (lldb::user_id_t id) return debugger_sp; } +#if 0 static void TestPromptFormats (StackFrame *frame) { @@ -1145,6 +1180,7 @@ TestPromptFormats (StackFrame *frame) printf ("what we got: %s\n", s.GetData()); } } +#endif static bool ScanFormatDescriptor (const char* var_name_begin, @@ -1421,6 +1457,96 @@ IsTokenWithFormat(const char *var_name_begin, const char *var, std::string &form 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 ( @@ -1678,6 +1804,13 @@ FormatPromptRecurse 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 @@ -1945,6 +2078,19 @@ FormatPromptRecurse } } } + 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:"); @@ -1953,6 +2099,15 @@ FormatPromptRecurse 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); + } + } } } } @@ -2205,7 +2360,29 @@ FormatPromptRecurse if (args.GetSize() > 0) { const char *open_paren = strchr (cstr, '('); - const char *close_paren = NULL; + 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)")) @@ -2228,16 +2405,30 @@ FormatPromptRecurse 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(); - const char *var_value = var_value_sp->GetValueAsCString(); + 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); + 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_value) - s.Printf ("%s=%s", var_name, var_value); + 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()); } @@ -2769,36 +2960,30 @@ Debugger::HandleProcessEvent (const EventSP &event_sp) const uint32_t event_type = event_sp->GetType(); ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get()); + StreamString output_stream; + StreamString error_stream; const bool gui_enabled = IsForwardingEvents(); - bool top_io_handler_hid = false; - if (gui_enabled == false) - top_io_handler_hid = HideTopIOHandler(); - assert (process_sp); - - if (event_type & Process::eBroadcastBitSTDOUT) + if (!gui_enabled) { - // The process has stdout available, get it and write it out to the - // appropriate place. - if (top_io_handler_hid) - GetProcessSTDOUT (process_sp.get(), NULL); - } - else if (event_type & Process::eBroadcastBitSTDERR) - { - // The process has stderr available, get it and write it out to the - // appropriate place. - if (top_io_handler_hid) - GetProcessSTDERR (process_sp.get(), NULL); - } - else if (event_type & Process::eBroadcastBitStateChanged) - { - // Drain all stout and stderr so we don't see any output come after - // we print our prompts - if (top_io_handler_hid) + bool pop_process_io_handler = false; + assert (process_sp); + + if (event_type & Process::eBroadcastBitSTDOUT || event_type & Process::eBroadcastBitStateChanged) { - StreamFileSP stream_sp (GetOutputFile()); - GetProcessSTDOUT (process_sp.get(), stream_sp.get()); - GetProcessSTDERR (process_sp.get(), NULL); + GetProcessSTDOUT (process_sp.get(), &output_stream); + } + + if (event_type & Process::eBroadcastBitSTDERR || event_type & Process::eBroadcastBitStateChanged) + { + GetProcessSTDERR (process_sp.get(), &error_stream); + } + + if (event_type & Process::eBroadcastBitStateChanged) + { + + // Drain all stout and stderr so we don't see any output come after + // we print our prompts // Something changed in the process; get the event and report the process's current status and location to // the user. StateType event_state = Process::ProcessEventData::GetStateFromEvent (event_sp.get()); @@ -2815,9 +3000,12 @@ Debugger::HandleProcessEvent (const EventSP &event_sp) case eStateStepping: case eStateDetached: { - stream_sp->Printf("Process %" PRIu64 " %s\n", - process_sp->GetID(), - StateAsCString (event_state)); + output_stream.Printf("Process %" PRIu64 " %s\n", + process_sp->GetID(), + StateAsCString (event_state)); + + if (event_state == eStateDetached) + pop_process_io_handler = true; } break; @@ -2826,7 +3014,8 @@ Debugger::HandleProcessEvent (const EventSP &event_sp) break; case eStateExited: - process_sp->GetStatus(*stream_sp); + process_sp->GetStatus(output_stream); + pop_process_io_handler = true; break; case eStateStopped: @@ -2842,86 +3031,91 @@ Debugger::HandleProcessEvent (const EventSP &event_sp) if (num_reasons == 1) { const char *reason = Process::ProcessEventData::GetRestartedReasonAtIndex (event_sp.get(), 0); - stream_sp->Printf("Process %" PRIu64 " stopped and restarted: %s\n", - process_sp->GetID(), - reason ? reason : ""); + output_stream.Printf("Process %" PRIu64 " stopped and restarted: %s\n", + process_sp->GetID(), + reason ? reason : ""); } else { - stream_sp->Printf("Process %" PRIu64 " stopped and restarted, reasons:\n", - process_sp->GetID()); + output_stream.Printf("Process %" PRIu64 " stopped and restarted, reasons:\n", + process_sp->GetID()); for (size_t i = 0; i < num_reasons; i++) { const char *reason = Process::ProcessEventData::GetRestartedReasonAtIndex (event_sp.get(), i); - stream_sp->Printf("\t%s\n", reason ? reason : ""); + output_stream.Printf("\t%s\n", reason ? reason : ""); } } } } else { - // Lock the thread list so it doesn't change on us - ThreadList &thread_list = process_sp->GetThreadList(); - Mutex::Locker locker (thread_list.GetMutex()); - - ThreadSP curr_thread (thread_list.GetSelectedThread()); - ThreadSP thread; - StopReason curr_thread_stop_reason = eStopReasonInvalid; - if (curr_thread) - curr_thread_stop_reason = curr_thread->GetStopReason(); - if (!curr_thread || - !curr_thread->IsValid() || - curr_thread_stop_reason == eStopReasonInvalid || - curr_thread_stop_reason == eStopReasonNone) + // Lock the thread list so it doesn't change on us, this is the scope for the locker: { - // Prefer a thread that has just completed its plan over another thread as current thread. - ThreadSP plan_thread; - ThreadSP other_thread; - const size_t num_threads = thread_list.GetSize(); - size_t i; - for (i = 0; i < num_threads; ++i) + ThreadList &thread_list = process_sp->GetThreadList(); + Mutex::Locker locker (thread_list.GetMutex()); + + ThreadSP curr_thread (thread_list.GetSelectedThread()); + ThreadSP thread; + StopReason curr_thread_stop_reason = eStopReasonInvalid; + if (curr_thread) + curr_thread_stop_reason = curr_thread->GetStopReason(); + if (!curr_thread || + !curr_thread->IsValid() || + curr_thread_stop_reason == eStopReasonInvalid || + curr_thread_stop_reason == eStopReasonNone) { - thread = thread_list.GetThreadAtIndex(i); - StopReason thread_stop_reason = thread->GetStopReason(); - switch (thread_stop_reason) + // Prefer a thread that has just completed its plan over another thread as current thread. + ThreadSP plan_thread; + ThreadSP other_thread; + const size_t num_threads = thread_list.GetSize(); + size_t i; + for (i = 0; i < num_threads; ++i) { - case eStopReasonInvalid: - case eStopReasonNone: - break; - - case eStopReasonTrace: - case eStopReasonBreakpoint: - case eStopReasonWatchpoint: - case eStopReasonSignal: - case eStopReasonException: - case eStopReasonExec: - case eStopReasonThreadExiting: - if (!other_thread) - other_thread = thread; - break; - case eStopReasonPlanComplete: - if (!plan_thread) - plan_thread = thread; - break; + thread = thread_list.GetThreadAtIndex(i); + StopReason thread_stop_reason = thread->GetStopReason(); + switch (thread_stop_reason) + { + case eStopReasonInvalid: + case eStopReasonNone: + break; + + case eStopReasonTrace: + case eStopReasonBreakpoint: + case eStopReasonWatchpoint: + case eStopReasonSignal: + case eStopReasonException: + case eStopReasonExec: + case eStopReasonThreadExiting: + if (!other_thread) + other_thread = thread; + break; + case eStopReasonPlanComplete: + if (!plan_thread) + plan_thread = thread; + break; + } } - } - if (plan_thread) - thread_list.SetSelectedThreadByID (plan_thread->GetID()); - else if (other_thread) - thread_list.SetSelectedThreadByID (other_thread->GetID()); - else - { - if (curr_thread && curr_thread->IsValid()) - thread = curr_thread; + if (plan_thread) + thread_list.SetSelectedThreadByID (plan_thread->GetID()); + else if (other_thread) + thread_list.SetSelectedThreadByID (other_thread->GetID()); else - thread = thread_list.GetThreadAtIndex(0); - - if (thread) - thread_list.SetSelectedThreadByID (thread->GetID()); + { + if (curr_thread && curr_thread->IsValid()) + thread = curr_thread; + else + thread = thread_list.GetThreadAtIndex(0); + + if (thread) + thread_list.SetSelectedThreadByID (thread->GetID()); + } } } + // Drop the ThreadList mutex by here, since GetThreadStatus below might have to run code, + // e.g. for Data formatters, and if we hold the ThreadList mutex, then the process is going to + // have a hard time restarting the process. if (GetTargetList().GetSelectedTarget().get() == &process_sp->GetTarget()) { @@ -2929,8 +3123,8 @@ Debugger::HandleProcessEvent (const EventSP &event_sp) const uint32_t start_frame = 0; const uint32_t num_frames = 1; const uint32_t num_frames_with_source = 1; - process_sp->GetStatus(*stream_sp); - process_sp->GetThreadStatus (*stream_sp, + process_sp->GetStatus(output_stream); + process_sp->GetThreadStatus (output_stream, only_threads_with_stop_reason, start_frame, num_frames, @@ -2940,20 +3134,49 @@ Debugger::HandleProcessEvent (const EventSP &event_sp) { uint32_t target_idx = GetTargetList().GetIndexOfTarget(process_sp->GetTarget().shared_from_this()); if (target_idx != UINT32_MAX) - stream_sp->Printf ("Target %d: (", target_idx); + output_stream.Printf ("Target %d: (", target_idx); else - stream_sp->Printf ("Target : ("); - process_sp->GetTarget().Dump (stream_sp.get(), eDescriptionLevelBrief); - stream_sp->Printf (") stopped.\n"); + output_stream.Printf ("Target : ("); + process_sp->GetTarget().Dump (&output_stream, eDescriptionLevelBrief); + output_stream.Printf (") stopped.\n"); } + + // Pop the process IO handler + pop_process_io_handler = true; } break; } } - } - if (top_io_handler_hid) - RefreshTopIOHandler(); + if (output_stream.GetSize() || error_stream.GetSize()) + { + StreamFileSP error_stream_sp (GetOutputFile()); + bool top_io_handler_hid = false; + + if (process_sp->ProcessIOHandlerIsActive() == false) + top_io_handler_hid = HideTopIOHandler(); + + if (output_stream.GetSize()) + { + StreamFileSP output_stream_sp (GetOutputFile()); + if (output_stream_sp) + output_stream_sp->Write (output_stream.GetData(), output_stream.GetSize()); + } + + if (error_stream.GetSize()) + { + StreamFileSP error_stream_sp (GetErrorFile()); + if (error_stream_sp) + error_stream_sp->Write (error_stream.GetData(), error_stream.GetSize()); + } + + if (top_io_handler_hid) + RefreshTopIOHandler(); + } + + if (pop_process_io_handler) + process_sp->PopProcessIOHandler(); + } } void diff --git a/source/Core/EmulateInstruction.cpp b/source/Core/EmulateInstruction.cpp index bf6c6d88b563..8349f54de4c7 100644 --- a/source/Core/EmulateInstruction.cpp +++ b/source/Core/EmulateInstruction.cpp @@ -75,7 +75,7 @@ EmulateInstruction::ReadRegister (const RegisterInfo *reg_info, RegisterValue& r } bool -EmulateInstruction::ReadRegister (uint32_t reg_kind, uint32_t reg_num, RegisterValue& reg_value) +EmulateInstruction::ReadRegister (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterValue& reg_value) { RegisterInfo reg_info; if (GetRegisterInfo(reg_kind, reg_num, reg_info)) @@ -84,7 +84,7 @@ EmulateInstruction::ReadRegister (uint32_t reg_kind, uint32_t reg_num, RegisterV } uint64_t -EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind, +EmulateInstruction::ReadRegisterUnsigned (lldb::RegisterKind reg_kind, uint32_t reg_num, uint64_t fail_value, bool *success_ptr) @@ -122,7 +122,7 @@ EmulateInstruction::WriteRegister (const Context &context, bool EmulateInstruction::WriteRegister (const Context &context, - uint32_t reg_kind, + lldb::RegisterKind reg_kind, uint32_t reg_num, const RegisterValue& reg_value) { @@ -135,7 +135,7 @@ EmulateInstruction::WriteRegister (const Context &context, bool EmulateInstruction::WriteRegisterUnsigned (const Context &context, - uint32_t reg_kind, + lldb::RegisterKind reg_kind, uint32_t reg_num, uint64_t uint_value) { @@ -392,7 +392,8 @@ EmulateInstruction::ReadRegisterDefault (EmulateInstruction *instruction, { StreamFile strm (stdout, false); strm.Printf (" Read Register (%s)\n", reg_info->name); - uint32_t reg_kind, reg_num; + lldb::RegisterKind reg_kind; + uint32_t reg_num; if (GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num)) reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num); else @@ -608,7 +609,7 @@ EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_ad bool EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info, - uint32_t ®_kind, + lldb::RegisterKind ®_kind, uint32_t ®_num) { // Generic and DWARF should be the two most popular register kinds when @@ -653,7 +654,8 @@ EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info, uint32_t EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo ®_info) { - uint32_t reg_kind, reg_num; + lldb::RegisterKind reg_kind; + uint32_t reg_num; if (reg_ctx && GetBestRegisterKindAndNumber (®_info, reg_kind, reg_num)) return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num); return LLDB_INVALID_REGNUM; diff --git a/source/Core/Error.cpp b/source/Core/Error.cpp index 7aabe5b386d4..03cfd41b288d 100644 --- a/source/Core/Error.cpp +++ b/source/Core/Error.cpp @@ -21,7 +21,7 @@ #include #include -#if defined (__arm__) && defined (__APPLE__) +#if (defined (__arm__) || defined (__arm64__) || defined (__aarch64__)) && defined (__APPLE__) #include #endif @@ -264,6 +264,35 @@ Error::SetMachError (uint32_t err) m_string.clear(); } +void +Error::SetExpressionError (lldb::ExpressionResults result, const char *mssg) +{ + m_code = result; + m_type = eErrorTypeExpression; + m_string = mssg; +} + +int +Error::SetExpressionErrorWithFormat (lldb::ExpressionResults result, const char *format, ...) +{ + int length = 0; + + if (format && format[0]) + { + va_list args; + va_start (args, format); + length = SetErrorStringWithVarArg (format, args); + va_end (args); + } + else + { + m_string.clear(); + } + m_code = result; + m_type = eErrorTypeExpression; + return length; +} + //---------------------------------------------------------------------- // Set accesssor for the error value and type. //---------------------------------------------------------------------- diff --git a/source/Core/Event.cpp b/source/Core/Event.cpp index 2d4899dd6dcb..bf5ff222a122 100644 --- a/source/Core/Event.cpp +++ b/source/Core/Event.cpp @@ -57,20 +57,19 @@ Event::Dump (Stream *s) const StreamString event_name; if (m_broadcaster->GetEventNames (event_name, m_type, false)) s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x (%s), data = ", - this, - m_broadcaster, + static_cast(this), + static_cast(m_broadcaster), m_broadcaster->GetBroadcasterName().GetCString(), - m_type, - event_name.GetString().c_str()); + m_type, event_name.GetString().c_str()); else s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x, data = ", - this, - m_broadcaster, - m_broadcaster->GetBroadcasterName().GetCString(), - m_type); + static_cast(this), + static_cast(m_broadcaster), + m_broadcaster->GetBroadcasterName().GetCString(), m_type); } else - s->Printf("%p Event: broadcaster = NULL, type = 0x%8.8x, data = ", this, m_type); + s->Printf("%p Event: broadcaster = NULL, type = 0x%8.8x, data = ", + static_cast(this), m_type); if (m_data_ap.get() == NULL) s->Printf (""); diff --git a/source/Core/FastDemangle.cpp b/source/Core/FastDemangle.cpp new file mode 100644 index 000000000000..00a75425b689 --- /dev/null +++ b/source/Core/FastDemangle.cpp @@ -0,0 +1,2203 @@ +//===-- FastDemangle.cpp ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include +#include +#include + +//#define DEBUG_FAILURES 1 +//#define DEBUG_SUBSTITUTIONS 1 +//#define DEBUG_TEMPLATE_ARGS 1 +//#define DEBUG_HIGHWATER 1 +//#define DEBUG_REORDERING 1 + +namespace { + +/// @brief Represents the collection of qualifiers on a type + +enum Qualifiers +{ + QualifierNone = 0, + QualifierConst = 1, + QualifierRestrict = 2, + QualifierVolatile = 4, + QualifierReference = 8, + QualifierRValueReference = 16, + QualifierPointer = 32 +}; + +/// @brief Categorizes the recognized operators + +enum class OperatorKind +{ + Unary, + Postfix, + Binary, + Ternary, + Other, + ConversionOperator, + Vendor, + NoMatch +}; + +/// @brief Represents one of the recognized two-character operator +/// abbreviations used when parsing operators as names and expressions + +struct Operator +{ + const char * name; + OperatorKind kind; +}; + +/// @brief Represents a range of characters in the output buffer, typically for +/// use with RewriteRange() + +struct BufferRange +{ + int offset; + int length; +}; + +/// @brief Transient state required while parsing a name + +struct NameState +{ + bool parse_function_params; + bool is_last_generic; + bool has_no_return_type; + BufferRange last_name_range; +}; + +/// @brief LLDB's fast C++ demangler +/// +/// This is an incomplete implementation designed to speed up the demangling +/// process that is often a bottleneck when LLDB stops a process for the first +/// time. Where the implementation doesn't know how to demangle a symbol it +/// fails gracefully to allow the caller to fall back to the existing demangler. +/// +/// Over time the full mangling spec should be supported without compromising +/// performance for the most common cases. + +class SymbolDemangler +{ +public: + + //---------------------------------------------------- + // Public API + //---------------------------------------------------- + + /// @brief Create a SymbolDemangler + /// + /// The newly created demangler allocates and owns scratch memory sufficient + /// for demangling typical symbols. Additional memory will be allocated if + /// needed and managed by the demangler instance. + + SymbolDemangler() + { + buffer = (char *) malloc(8192); + buffer_end = buffer + 8192; + owns_buffer = true; + + rewrite_ranges = (BufferRange *) malloc(128 * sizeof(BufferRange)); + rewrite_ranges_size = 128; + owns_rewrite_ranges = true; + } + + /// @brief Create a SymbolDemangler that uses provided scratch memory + /// + /// The provided memory is not owned by the demangler. It will be + /// overwritten during calls to GetDemangledCopy() but can be used for + /// other purposes between calls. The provided memory will not be freed + /// when this instance is destroyed. + /// + /// If demangling a symbol requires additional space it will be allocated + /// and managed by the demangler instance. + /// + /// @param storage_ptr Valid pointer to at least storage_size bytes of + /// space that the SymbolDemangler can use during demangling + /// + /// @param storage_size Number of bytes of space available scratch memory + /// referenced by storage_ptr + + SymbolDemangler(void * storage_ptr, int storage_size) + { + // Use up to 1/8th of the provided space for rewrite ranges + rewrite_ranges_size = (storage_size >> 3) / sizeof(BufferRange); + rewrite_ranges = (BufferRange *) storage_ptr; + owns_rewrite_ranges = false; + + // Use the rest for the character buffer + buffer = (char *) storage_ptr + rewrite_ranges_size * sizeof(BufferRange); + buffer_end = (const char *)storage_ptr + storage_size; + owns_buffer = false; + } + + /// @brief Destroys the SymbolDemangler and deallocates any scratch + /// memory that it owns + + ~SymbolDemangler() + { + if (owns_buffer) free(buffer); + if (owns_rewrite_ranges) free(rewrite_ranges); + } + +#ifdef DEBUG_HIGHWATER + int highwater_store = 0; + int highwater_buffer = 0; +#endif + + /// @brief Parses the provided mangled name and returns a newly allocated + /// demangling + /// + /// @param mangled_name Valid null-terminated C++ mangled name following + /// the Itanium C++ ABI mangling specification as implemented by Clang + /// + /// @result Newly allocated null-terminated demangled name when demangling + /// is succesful, and nullptr when demangling fails. The caller is + /// responsible for freeing the allocated memory. + + char * GetDemangledCopy(const char * mangled_name, + long mangled_name_length = 0) + { + if (!ParseMangling(mangled_name, mangled_name_length)) return nullptr; + +#ifdef DEBUG_HIGHWATER + int rewrite_count = next_substitute_index + + (rewrite_ranges_size - 1 - next_template_arg_index); + int buffer_size = (int)(write_ptr - buffer); + if (rewrite_count > highwater_store) highwater_store = rewrite_count; + if (buffer_size > highwater_buffer) highwater_buffer = buffer_size; +#endif + + int length = (int)(write_ptr - buffer); + char * copy = (char *)malloc(length + 1); + memcpy(copy, buffer, length); + copy[length] = '\0'; + return copy; + } + +private: + + //---------------------------------------------------- + // Grow methods + // + // Manage the storage used during demangling + //---------------------------------------------------- + + void GrowBuffer(long min_growth = 0) + { + // By default, double the size of the buffer + long growth = buffer_end - buffer; + + // Avoid growing by more than 1MB at a time + if (growth > 1 << 20) growth = 1 << 20; + + // ... but never grow by less than requested, + // or 1K, whichever is greater + if (min_growth < 1024) min_growth = 1024; + if (growth < min_growth) growth = min_growth; + + // Allocate the new buffer and migrate content + long new_size = (buffer_end - buffer) + growth; + char * new_buffer = (char *)malloc(new_size); + memcpy(new_buffer, buffer, write_ptr - buffer); + if (owns_buffer) free(buffer); + owns_buffer = true; + + // Update references to the new buffer + write_ptr = new_buffer + (write_ptr - buffer); + buffer = new_buffer; + buffer_end = buffer + new_size; + } + + void GrowRewriteRanges() + { + // By default, double the size of the array + int growth = rewrite_ranges_size; + + // Apply reasonable minimum and maximum sizes for growth + if (growth > 128) growth = 128; + if (growth < 16) growth = 16; + + // Allocate the new array and migrate content + int bytes = (rewrite_ranges_size + growth) * sizeof(BufferRange); + BufferRange * new_ranges = (BufferRange *) malloc(bytes); + for (int index = 0; index < next_substitute_index; index++) + { + new_ranges[index] = rewrite_ranges[index]; + } + for (int index = rewrite_ranges_size - 1; + index > next_template_arg_index; index--) + { + new_ranges[index + growth] = rewrite_ranges[index]; + } + if (owns_rewrite_ranges) free(rewrite_ranges); + owns_rewrite_ranges = true; + + // Update references to the new array + rewrite_ranges = new_ranges; + rewrite_ranges_size += growth; + next_template_arg_index += growth; + } + + //---------------------------------------------------- + // Range and state management + //---------------------------------------------------- + + int GetStartCookie() + { + return (int)(write_ptr - buffer); + } + + BufferRange EndRange(int start_cookie) + { + return { start_cookie, (int)(write_ptr - (buffer + start_cookie)) }; + } + + void ReorderRange(BufferRange source_range, int insertion_point_cookie) + { + // Ensure there's room the preserve the source range + if (write_ptr + source_range.length > buffer_end) + { + GrowBuffer(write_ptr + source_range.length - buffer_end); + } + + // Reorder the content + memcpy(write_ptr, buffer + source_range.offset, source_range.length); + memmove(buffer + insertion_point_cookie + source_range.length, + buffer + insertion_point_cookie, + source_range.offset - insertion_point_cookie); + memcpy(buffer + insertion_point_cookie, write_ptr, source_range.length); + + // Fix up rewritable ranges, covering both substitutions and templates + int index = 0; + while (true) + { + if (index == next_substitute_index) index = next_template_arg_index + 1; + if (index == rewrite_ranges_size) break; + + // Affected ranges are either shuffled forward when after the + // insertion but before the source, or backward when inside the + // source + int candidate_offset = rewrite_ranges[index].offset; + if (candidate_offset >= insertion_point_cookie) + { + if (candidate_offset < source_range.offset) + { + rewrite_ranges[index].offset += source_range.length; + } + else if (candidate_offset >= source_range.offset) + { + rewrite_ranges[index].offset -= + (source_range.offset - insertion_point_cookie); + } + } + ++index; + } + } + + void EndSubstitution(int start_cookie) + { + if (next_substitute_index == next_template_arg_index) GrowRewriteRanges(); + + int index = next_substitute_index++; + rewrite_ranges[index] = EndRange(start_cookie); +#ifdef DEBUG_SUBSTITUTIONS + printf("Saved substitution # %d = %.*s\n", index, + rewrite_ranges[index].length, buffer + start_cookie); +#endif + } + + void EndTemplateArg(int start_cookie) + { + if (next_substitute_index == next_template_arg_index) GrowRewriteRanges(); + + int index = next_template_arg_index--; + rewrite_ranges[index] = EndRange(start_cookie); +#ifdef DEBUG_TEMPLATE_ARGS + printf("Saved template arg # %d = %.*s\n", + rewrite_ranges_size - index - 1, + rewrite_ranges[index].length, buffer + start_cookie); +#endif + } + + void ResetTemplateArgs() + { + //TODO: this works, but is it the right thing to do? + // Should we push/pop somehow at the call sites? + next_template_arg_index = rewrite_ranges_size - 1; + } + + //---------------------------------------------------- + // Write methods + // + // Appends content to the existing output buffer + //---------------------------------------------------- + + void Write(char character) + { + if (write_ptr == buffer_end) GrowBuffer(); + *write_ptr++ = character; + } + + void Write(const char * content) + { + Write(content, strlen(content)); + } + + void Write(const char * content, long content_length) + { + char * end_write_ptr = write_ptr + content_length; + if (end_write_ptr > buffer_end) + { + GrowBuffer(end_write_ptr - buffer_end); + end_write_ptr = write_ptr + content_length; + } + memcpy(write_ptr, content, content_length); + write_ptr = end_write_ptr; + } +#define WRITE(x) Write(x, sizeof(x) - 1) + + void WriteTemplateStart() + { + Write('<'); + } + + void WriteTemplateEnd() + { + // Put a space between terminal > characters when nesting templates + if (write_ptr != buffer && *(write_ptr - 1) == '>') WRITE(" >"); + else Write('>'); + } + + void WriteCommaSpace() + { + WRITE(", "); + } + + void WriteNamespaceSeparator() + { + WRITE("::"); + } + + void WriteStdPrefix() + { + WRITE("std::"); + } + + void WriteQualifiers(int qualifiers, bool space_before_reference = true) + { + if (qualifiers & QualifierPointer) Write('*'); + if (qualifiers & QualifierConst) WRITE(" const"); + if (qualifiers & QualifierVolatile) WRITE(" volatile"); + if (qualifiers & QualifierRestrict) WRITE(" restrict"); + if (qualifiers & QualifierReference) + { + if (space_before_reference) WRITE(" &"); + else Write('&'); + } + if (qualifiers & QualifierRValueReference) + { + if (space_before_reference) WRITE(" &&"); + else WRITE("&&"); + } + } + + //---------------------------------------------------- + // Rewrite methods + // + // Write another copy of content already present + // earlier in the output buffer + //---------------------------------------------------- + + void RewriteRange(BufferRange range) + { + Write(buffer + range.offset, range.length); + } + + bool RewriteSubstitution(int index) + { + if (index < 0 || index >= next_substitute_index) + { +#ifdef DEBUG_FAILURES + printf("*** Invalid substitution #%d\n", index); +#endif + return false; + } + RewriteRange(rewrite_ranges[index]); + return true; + } + + bool RewriteTemplateArg(int template_index) + { + int index = rewrite_ranges_size - 1 - template_index; + if (template_index < 0 || index <= next_template_arg_index) + { +#ifdef DEBUG_FAILURES + printf("*** Invalid template arg reference #%d\n", template_index); +#endif + return false; + } + RewriteRange(rewrite_ranges[index]); + return true; + } + + //---------------------------------------------------- + // TryParse methods + // + // Provide information with return values instead of + // writing to the output buffer + // + // Values indicating failure guarantee that the pre- + // call read_ptr is unchanged + //---------------------------------------------------- + + int TryParseNumber() + { + unsigned char digit = *read_ptr - '0'; + if (digit > 9) return -1; + + int count = digit; + while (true) + { + digit = *++read_ptr - '0'; + if (digit > 9) break; + + count = count * 10 + digit; + } + return count; + } + + int TryParseBase36Number() + { + char digit = *read_ptr; + int count; + if (digit >= '0' && digit <= '9') count = digit -= '0'; + else if (digit >= 'A' && digit <= 'Z') count = digit -= ('A' - 10); + else return -1; + + while (true) + { + digit = *++read_ptr; + if (digit >= '0' && digit <= '9') digit -= '0'; + else if (digit >= 'A' && digit <= 'Z') digit -= ('A' - 10); + else break; + + count = count * 36 + digit; + } + return count; + } + + // ::= v # void + // ::= w # wchar_t + // ::= b # bool + // ::= c # char + // ::= a # signed char + // ::= h # unsigned char + // ::= s # short + // ::= t # unsigned short + // ::= i # int + // ::= j # unsigned int + // ::= l # long + // ::= m # unsigned long + // ::= x # long long, __int64 + // ::= y # unsigned long long, __int64 + // ::= n # __int128 + // ::= o # unsigned __int128 + // ::= f # float + // ::= d # double + // ::= e # long double, __float80 + // ::= g # __float128 + // ::= z # ellipsis + // ::= Dd # IEEE 754r decimal floating point (64 bits) + // ::= De # IEEE 754r decimal floating point (128 bits) + // ::= Df # IEEE 754r decimal floating point (32 bits) + // ::= Dh # IEEE 754r half-precision floating point (16 bits) + // ::= Di # char32_t + // ::= Ds # char16_t + // ::= Da # auto (in dependent new-expressions) + // ::= Dn # std::nullptr_t (i.e., decltype(nullptr)) + // ::= u # vendor extended type + + const char * TryParseBuiltinType() + { + switch (*read_ptr++) + { + case 'v': return "void"; + case 'w': return "wchar_t"; + case 'b': return "bool"; + case 'c': return "char"; + case 'a': return "signed char"; + case 'h': return "unsigned char"; + case 's': return "short"; + case 't': return "unsigned short"; + case 'i': return "int"; + case 'j': return "unsigned int"; + case 'l': return "long"; + case 'm': return "unsigned long"; + case 'x': return "long long"; + case 'y': return "unsigned long long"; + case 'n': return "__int128"; + case 'o': return "unsigned __int128"; + case 'f': return "float"; + case 'd': return "double"; + case 'e': return "long double"; + case 'g': return "__float128"; + case 'z': return "..."; + case 'D': + { + switch (*read_ptr++) + { + case 'd': return "decimal64"; + case 'e': return "decimal128"; + case 'f': return "decimal32"; + case 'h': return "decimal16"; + case 'i': return "char32_t"; + case 's': return "char16_t"; + case 'a': return "auto"; + case 'c': return "decltype(auto)"; + case 'n': return "std::nullptr_t"; + default: + --read_ptr; + } + } + } + --read_ptr; + return nullptr; + } + + // + // ::= aa # && + // ::= ad # & (unary) + // ::= an # & + // ::= aN # &= + // ::= aS # = + // ::= cl # () + // ::= cm # , + // ::= co # ~ + // ::= da # delete[] + // ::= de # * (unary) + // ::= dl # delete + // ::= dv # / + // ::= dV # /= + // ::= eo # ^ + // ::= eO # ^= + // ::= eq # == + // ::= ge # >= + // ::= gt # > + // ::= ix # [] + // ::= le # <= + // ::= ls # << + // ::= lS # <<= + // ::= lt # < + // ::= mi # - + // ::= mI # -= + // ::= ml # * + // ::= mL # *= + // ::= mm # -- (postfix in context) + // ::= na # new[] + // ::= ne # != + // ::= ng # - (unary) + // ::= nt # ! + // ::= nw # new + // ::= oo # || + // ::= or # | + // ::= oR # |= + // ::= pm # ->* + // ::= pl # + + // ::= pL # += + // ::= pp # ++ (postfix in context) + // ::= ps # + (unary) + // ::= pt # -> + // ::= qu # ? + // ::= rm # % + // ::= rM # %= + // ::= rs # >> + // ::= rS # >>= + // ::= cv # (cast) + // ::= v # vendor extended operator + + Operator TryParseOperator() + { + switch (*read_ptr++) + { + case 'a': + switch (*read_ptr++) + { + case 'a': return { "&&", OperatorKind::Binary }; + case 'd': return { "&", OperatorKind::Unary }; + case 'n': return { "&", OperatorKind::Binary }; + case 'N': return { "&=", OperatorKind::Binary }; + case 'S': return { "=", OperatorKind::Binary }; + } + --read_ptr; + break; + case 'c': + switch (*read_ptr++) + { + case 'l': return { "()", OperatorKind::Other }; + case 'm': return { ",", OperatorKind::Other }; + case 'o': return { "~", OperatorKind::Unary }; + case 'v': return { nullptr, OperatorKind::ConversionOperator }; + } + --read_ptr; + break; + case 'd': + switch (*read_ptr++) + { + case 'a': return { " delete[]", OperatorKind::Other }; + case 'e': return { "*", OperatorKind::Unary }; + case 'l': return { " delete", OperatorKind::Other }; + case 'v': return { "/", OperatorKind::Binary }; + case 'V': return { "/=", OperatorKind::Binary }; + } + --read_ptr; + break; + case 'e': + switch (*read_ptr++) + { + case 'o': return { "^", OperatorKind::Binary }; + case 'O': return { "^=", OperatorKind::Binary }; + case 'q': return { "==", OperatorKind::Binary }; + } + --read_ptr; + break; + case 'g': + switch (*read_ptr++) + { + case 'e': return { ">=", OperatorKind::Binary }; + case 't': return { ">", OperatorKind::Binary }; + } + --read_ptr; + break; + case 'i': + switch (*read_ptr++) + { + case 'x': return { "[]", OperatorKind::Other }; + } + --read_ptr; + break; + case 'l': + switch (*read_ptr++) + { + case 'e': return { "<=", OperatorKind::Binary }; + case 's': return { "<<", OperatorKind::Binary }; + case 'S': return { "<<=", OperatorKind::Binary }; + case 't': return { "<", OperatorKind::Binary }; + // case 'i': return { "?", OperatorKind::Binary }; + } + --read_ptr; + break; + case 'm': + switch (*read_ptr++) + { + case 'i': return { "-", OperatorKind::Binary }; + case 'I': return { "-=", OperatorKind::Binary }; + case 'l': return { "*", OperatorKind::Binary }; + case 'L': return { "*=", OperatorKind::Binary }; + case 'm': return { "--", OperatorKind::Postfix }; + } + --read_ptr; + break; + case 'n': + switch (*read_ptr++) + { + case 'a': return { " new[]", OperatorKind::Other }; + case 'e': return { "!=", OperatorKind::Binary }; + case 'g': return { "-", OperatorKind::Unary }; + case 't': return { "!", OperatorKind::Unary }; + case 'w': return { " new", OperatorKind::Other }; + } + --read_ptr; + break; + case 'o': + switch (*read_ptr++) + { + case 'o': return { "||", OperatorKind::Binary }; + case 'r': return { "|", OperatorKind::Binary }; + case 'R': return { "|=", OperatorKind::Binary }; + } + --read_ptr; + break; + case 'p': + switch (*read_ptr++) + { + case 'm': return { "->*", OperatorKind::Binary }; + case 's': return { "+", OperatorKind::Unary }; + case 'l': return { "+", OperatorKind::Binary }; + case 'L': return { "+=", OperatorKind::Binary }; + case 'p': return { "++", OperatorKind::Postfix }; + case 't': return { "->", OperatorKind::Binary }; + } + --read_ptr; + break; + case 'q': + switch (*read_ptr++) + { + case 'u': return { "?", OperatorKind::Ternary }; + } + --read_ptr; + break; + case 'r': + switch (*read_ptr++) + { + case 'm': return { "%", OperatorKind::Binary }; + case 'M': return { "%=", OperatorKind::Binary }; + case 's': return { ">>", OperatorKind::Binary }; + case 'S': return { ">=", OperatorKind::Binary }; + } + --read_ptr; + break; + case 'v': + char digit = *read_ptr; + if (digit >= '0' && digit <= '9') + { + read_ptr++; + return { nullptr, OperatorKind::Vendor }; + } + --read_ptr; + break; + } + --read_ptr; + return { nullptr, OperatorKind::NoMatch }; + } + + // ::= [r] [V] [K] + // ::= R # & ref-qualifier + // ::= O # && ref-qualifier + + int TryParseQualifiers(bool allow_cv, bool allow_ro) + { + int qualifiers = QualifierNone; + char next = *read_ptr; + if (allow_cv) + { + if (next == 'r') // restrict + { + qualifiers |= QualifierRestrict; + next = *++read_ptr; + } + if (next == 'V') // volatile + { + qualifiers |= QualifierVolatile; + next = *++read_ptr; + } + if (next == 'K') // const + { + qualifiers |= QualifierConst; + next = *++read_ptr; + } + } + if (allow_ro) + { + if (next == 'R') + { + ++read_ptr; + qualifiers |= QualifierReference; + } + else if (next =='O') + { + ++read_ptr; + qualifiers |= QualifierRValueReference; + } + } + return qualifiers; + } + + // := _ # when number < 10 + // := __ _ # when number >= 10 + // extension := decimal-digit+ + + int TryParseDiscriminator() + { + const char * discriminator_start = read_ptr; + + // Test the extension first, since it's what Clang uses + int discriminator_value = TryParseNumber(); + if (discriminator_value != -1) return discriminator_value; + + char next = *read_ptr; + if (next == '_') + { + next = *++read_ptr; + if (next == '_') + { + ++read_ptr; + discriminator_value = TryParseNumber(); + if (discriminator_value != -1 && *read_ptr++ != '_') + { + return discriminator_value; + } + } + else if (next >= '0' && next <= '9') + { + ++read_ptr; + return next - '0'; + } + } + + // Not a valid discriminator + read_ptr = discriminator_start; + return -1; + } + + //---------------------------------------------------- + // Parse methods + // + // Consume input starting from read_ptr and produce + // buffered output at write_ptr + // + // Failures return false and may leave read_ptr in an + // indeterminate state + //---------------------------------------------------- + + bool Parse(char character) + { + if (*read_ptr++ == character) return true; +#ifdef DEBUG_FAILURES + printf("*** Expected '%c'\n", character); +#endif + return false; + } + + // ::= [n] + + bool ParseNumber(bool allow_negative = false) + { + if (allow_negative && *read_ptr == 'n') + { + Write('-'); + ++read_ptr; + } + const char * before_digits = read_ptr; + while (true) + { + unsigned char digit = *read_ptr - '0'; + if (digit > 9) break; + ++read_ptr; + } + if (int digit_count = (int)(read_ptr - before_digits)) + { + Write(before_digits, digit_count); + return true; + } +#ifdef DEBUG_FAILURES + printf("*** Expected number\n"); +#endif + return false; + } + + // ::= S _ + // ::= S_ + // ::= Sa # ::std::allocator + // ::= Sb # ::std::basic_string + // ::= Ss # ::std::basic_string < char, + // ::std::char_traits, + // ::std::allocator > + // ::= Si # ::std::basic_istream > + // ::= So # ::std::basic_ostream > + // ::= Sd # ::std::basic_iostream > + + bool ParseSubstitution() + { + const char * substitution; + switch (*read_ptr) + { + case 'a': substitution = "std::allocator"; break; + case 'b': substitution = "std::basic_string"; break; + case 's': substitution = "std::string"; break; + case 'i': substitution = "std::istream"; break; + case 'o': substitution = "std::ostream"; break; + case 'd': substitution = "std::iostream"; break; + default: + // A failed attempt to parse a number will return -1 which turns out to be + // perfect here as S_ is the first substitution, S0_ the next and so forth + int substitution_index = TryParseBase36Number(); + if (*read_ptr++ != '_') + { +#ifdef DEBUG_FAILURES + printf("*** Expected terminal _ in substitution\n"); +#endif + return false; + } + return RewriteSubstitution(substitution_index + 1); + } + Write(substitution); + ++read_ptr; + return true; + } + + // ::= F [Y] [] E + // + // ::= + # types are possible return type, then parameter types + + bool ParseFunctionType(int inner_qualifiers = QualifierNone) + { +#ifdef DEBUG_FAILURES + printf("*** Function types not supported\n"); +#endif + //TODO: first steps toward an implementation follow, but they're far + // from complete. Function types tend to bracket other types eg: + // int (*)() when used as the type for "name" becomes int (*name)(). + // This makes substitution et al ... interesting. + return false; + + if (*read_ptr == 'Y') ++read_ptr;; + + int return_type_start_cookie = GetStartCookie(); + if (!ParseType()) return false; + Write(' '); + + int insert_cookie = GetStartCookie(); + Write('('); + bool first_param = true; + int qualifiers = QualifierNone; + while (true) + { + switch (*read_ptr) + { + case 'E': + ++read_ptr; + Write(')'); + break; + case 'v': + ++read_ptr; + continue; + case 'R': + case 'O': + if (*(read_ptr + 1) == 'E') + { + qualifiers = TryParseQualifiers(false, true); + Parse('E'); + break; + } + // fallthrough + default: + { + if (first_param) first_param = false; + else WriteCommaSpace(); + + if (!ParseType()) return false; + continue; + } + } + break; + } + + if (qualifiers) + { + WriteQualifiers(qualifiers); + EndSubstitution(return_type_start_cookie); + } + + if (inner_qualifiers) + { + int qualifier_start_cookie = GetStartCookie(); + Write('('); + WriteQualifiers(inner_qualifiers); + Write(')'); + ReorderRange(EndRange(qualifier_start_cookie), insert_cookie); + } + return true; + } + + // ::= A _ + // ::= A [] _ + + bool ParseArrayType(int qualifiers = QualifierNone) + { +#ifdef DEBUG_FAILURES + printf("*** Array type unsupported\n"); +#endif + //TODO: We fail horribly when recalling these as substitutions or + // templates and trying to constify them eg: + // _ZN4llvm2cl5applyIA28_cNS0_3optIbLb0ENS0_6parserIbEEEEEEvRKT_PT0_ + // + //TODO: Chances are we don't do any better with references and pointers + // that should be type (&) [] instead of type & [] + + return false; + + if (*read_ptr == '_') + { + ++read_ptr; + if (!ParseType()) return false; + if (qualifiers) WriteQualifiers(qualifiers); + WRITE(" []"); + return true; + } + else + { + const char * before_digits = read_ptr; + if (TryParseNumber() != -1) + { + const char * after_digits = read_ptr; + if (!Parse('_')) return false; + if (!ParseType()) return false; + if (qualifiers) WriteQualifiers(qualifiers); + Write(' '); + Write('['); + Write(before_digits, after_digits - before_digits); + } + else + { + int type_insertion_cookie = GetStartCookie(); + if (!ParseExpression()) return false; + if (!Parse('_')) return false; + + int type_start_cookie = GetStartCookie(); + if (!ParseType()) return false; + if (qualifiers) WriteQualifiers(qualifiers); + Write(' '); + Write('['); + ReorderRange(EndRange(type_start_cookie), type_insertion_cookie); + } + Write(']'); + return true; + } + } + + // ::= M + + //TODO: Determine how to handle pointers to function members correctly, + // currently not an issue because we don't have function types at all... + bool ParsePointerToMemberType() + { + int insertion_cookie = GetStartCookie(); + Write(' '); + if (!ParseType()) return false; + WRITE("::*"); + + int type_cookie = GetStartCookie(); + if (!ParseType()) return false; + ReorderRange(EndRange(type_cookie), insertion_cookie); + return true; + } + + // ::= T_ # first template parameter + // ::= T _ + + bool ParseTemplateParam() + { + int count = TryParseNumber(); + if (!Parse('_')) return false; + + // When no number is present we get -1, which is convenient since + // T_ is the zeroth element T0_ is element 1, and so on + return RewriteTemplateArg(count + 1); + } + + // ::= + // ::= + // ::= + // ::= + // ::= + // ::= + // ::= + // ::= + // ::= + // ::= + // ::= P # pointer-to + // ::= R # reference-to + // ::= O # rvalue reference-to (C++0x) + // ::= C # complex pair (C 2000) + // ::= G # imaginary (C 2000) + // ::= Dp # pack expansion (C++0x) + // ::= U # vendor extended type qualifier + // extension := U # objc-type + // extension := # starts with Dv + + // ::= objcproto # k0 = 9 + + k1 + // := # PU<11+>objcproto 11objc_object 11objc_object -> id + + bool ParseType() + { +#ifdef DEBUG_FAILURES + const char * failed_type = read_ptr; +#endif + int type_start_cookie = GetStartCookie(); + bool suppress_substitution = false; + + int qualifiers = TryParseQualifiers(true, false); + switch (*read_ptr) + { + case 'D': + ++read_ptr; + switch (*read_ptr++) + { + case 'p': + if (!ParseType()) return false; + break; + case 'T': + case 't': + case 'v': + default: +#ifdef DEBUG_FAILURES + printf("*** Unsupported type: %.3s\n", failed_type); +#endif + return false; + } + break; + case 'T': + ++read_ptr; + if (!ParseTemplateParam()) return false; + break; + case 'M': + ++read_ptr; + if (!ParsePointerToMemberType()) return false; + break; + case 'A': + ++read_ptr; + if (!ParseArrayType()) return false; + break; + case 'F': + ++read_ptr; + if (!ParseFunctionType()) return false; + break; + case 'S': + if (*++read_ptr == 't') + { + ++read_ptr; + WriteStdPrefix(); + if (!ParseName()) return false; + } + else + { + suppress_substitution = true; + if (!ParseSubstitution()) return false; + } + break; + case 'P': + { + switch (*++read_ptr) + { + case 'F': + ++read_ptr; + if (!ParseFunctionType(QualifierPointer)) return false; + break; + default: + if (!ParseType()) return false; + Write('*'); + break; + } + break; + } + case 'R': + { + ++read_ptr; + if (!ParseType()) return false; + Write('&'); + break; + } + case 'O': + { + ++read_ptr; + if (!ParseType()) return false; + Write('&'); + Write('&'); + break; + } + case 'C': + case 'G': + case 'U': +#ifdef DEBUG_FAILURES + printf("*** Unsupported type: %.3s\n", failed_type); +#endif + return false; + // Test for common cases to avoid TryParseBuiltinType() overhead + case 'N': + case 'Z': + case 'L': + if (!ParseName()) return false; + break; + default: + if (const char * builtin = TryParseBuiltinType()) + { + Write(builtin); + suppress_substitution = true; + } + else + { + if (!ParseName()) return false; + } + break; + } + + // Allow base substitutions to be suppressed, but always record + // substitutions for the qualified variant + if (!suppress_substitution) EndSubstitution(type_start_cookie); + if (qualifiers) + { + WriteQualifiers(qualifiers, false); + EndSubstitution(type_start_cookie); + } + return true; + } + + // ::= Ut [ ] _ + // ::= + // + // ::= Ul E [ ] _ + // + // ::= + # Parameter types or "v" if the lambda has no parameters + + bool ParseUnnamedTypeName(NameState & name_state) + { + switch (*read_ptr++) + { + case 't': + { + int cookie = GetStartCookie(); + WRITE("'unnamed"); + const char * before_digits = read_ptr; + if (TryParseNumber() != -1) Write(before_digits, + read_ptr - before_digits); + if (!Parse('_')) return false; + Write('\''); + name_state.last_name_range = EndRange(cookie); + return true; + } + case 'b': + { + int cookie = GetStartCookie(); + WRITE("'block"); + const char * before_digits = read_ptr; + if (TryParseNumber() != -1) Write(before_digits, + read_ptr - before_digits); + if (!Parse('_')) return false; + Write('\''); + name_state.last_name_range = EndRange(cookie); + return true; + } + case 'l': +#ifdef DEBUG_FAILURES + printf("*** Lambda type names unsupported\n"); +#endif + return false; + } +#ifdef DEBUG_FAILURES + printf("*** Unknown unnamed type %.3s\n", read_ptr - 2); +#endif + return false; + } + + // ::= C1 # complete object constructor + // ::= C2 # base object constructor + // ::= C3 # complete object allocating constructor + + bool ParseCtor(NameState & name_state) + { + char next = *read_ptr; + if (next == '1' || next == '2' || next == '3' || next == '5') + { + RewriteRange(name_state.last_name_range); + name_state.has_no_return_type = true; + ++read_ptr; + return true; + } +#ifdef DEBUG_FAILURES + printf("*** Broken constructor\n"); +#endif + return false; + } + + // ::= D0 # deleting destructor + // ::= D1 # complete object destructor + // ::= D2 # base object destructor + + bool ParseDtor(NameState & name_state) + { + char next = *read_ptr; + if (next == '0' || next == '1' || next == '2' || next == '5') + { + Write('~'); + RewriteRange(name_state.last_name_range); + name_state.has_no_return_type = true; + ++read_ptr; + return true; + } +#ifdef DEBUG_FAILURES + printf("*** Broken destructor\n"); +#endif + return false; + } + + // See TryParseOperator() + + bool ParseOperatorName(NameState & name_state) + { +#ifdef DEBUG_FAILURES + const char * operator_ptr = read_ptr; +#endif + Operator parsed_operator = TryParseOperator(); + if (parsed_operator.name) + { + WRITE("operator"); + Write(parsed_operator.name); + return true; + } + + // Handle special operators + switch (parsed_operator.kind) + { + case OperatorKind::Vendor: + WRITE("operator "); + return ParseSourceName(); + case OperatorKind::ConversionOperator: + ResetTemplateArgs(); + name_state.has_no_return_type = true; + WRITE("operator "); + return ParseType(); + default: +#ifdef DEBUG_FAILURES + printf("*** Unknown operator: %.2s\n", operator_ptr); +#endif + return false; + } + } + + // ::= + + bool ParseSourceName() + { + int count = TryParseNumber(); + if (count == -1) + { +#ifdef DEBUG_FAILURES + printf("*** Malformed source name, missing length count\n"); +#endif + return false; + } + + const char * next_read_ptr = read_ptr + count; + if (next_read_ptr > read_end) + { +#ifdef DEBUG_FAILURES + printf("*** Malformed source name, premature termination\n"); +#endif + return false; + } + + if (count >= 10 && strncmp(read_ptr, "_GLOBAL__N", 10) == 0) WRITE("(anonymous namespace)"); + else Write(read_ptr, count); + + read_ptr = next_read_ptr; + return true; + } + + // ::= + // ::= + // ::= + // ::= + + bool ParseUnqualifiedName(NameState & name_state) + { + // Note that these are detected directly in ParseNestedName for + // performance rather than switching on the same options twice + char next = *read_ptr; + switch (next) + { + case 'C': + ++read_ptr; + return ParseCtor(name_state); + case 'D': + ++read_ptr; + return ParseDtor(name_state); + case 'U': + ++read_ptr; + return ParseUnnamedTypeName(name_state); + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + int name_start_cookie = GetStartCookie(); + if (!ParseSourceName()) return false; + name_state.last_name_range = EndRange(name_start_cookie); + return true; + } + default: + return ParseOperatorName(name_state); + }; + } + + // ::= + // ::= St # ::std:: + // extension ::= StL + + bool ParseUnscopedName(NameState & name_state) + { + if (*read_ptr == 'S' && *(read_ptr + 1) == 't') + { + WriteStdPrefix(); + if (*(read_ptr += 2) == 'L') ++read_ptr; + } + return ParseUnqualifiedName(name_state); + } + + bool ParseIntegerLiteral(const char * prefix, const char * suffix, + bool allow_negative) + { + if (prefix) Write(prefix); + if (!ParseNumber(allow_negative)) return false; + if (suffix) Write(suffix); + return Parse('E'); + } + + bool ParseBooleanLiteral() + { + switch (*read_ptr++) + { + case '0': WRITE("false"); break; + case '1': WRITE("true"); break; + default: +#ifdef DEBUG_FAILURES + printf("*** Boolean literal not 0 or 1\n"); +#endif + return false; + } + return Parse('E'); + } + + // ::= L E # integer literal + // ::= L E # floating literal + // ::= L E # string literal + // ::= L E # nullptr literal (i.e., "LDnE") + // ::= L _ E # complex floating point literal (C 2000) + // ::= L E # external name + + bool ParseExpressionPrimary() + { + switch (*read_ptr++) + { + case 'b': return ParseBooleanLiteral(); + case 'x': return ParseIntegerLiteral(nullptr, "ll", true); + case 'l': return ParseIntegerLiteral(nullptr, "l", true); + case 'i': return ParseIntegerLiteral(nullptr, nullptr, true); + case 'n': return ParseIntegerLiteral("(__int128)", nullptr, true); + case 'j': return ParseIntegerLiteral(nullptr, "u", false); + case 'm': return ParseIntegerLiteral(nullptr, "ul", false); + case 'y': return ParseIntegerLiteral(nullptr, "ull", false); + case 'o': return ParseIntegerLiteral("(unsigned __int128)", + nullptr, false); + case '_': + if (*read_ptr++ == 'Z') + { + if (!ParseEncoding()) return false; + return Parse('E'); + } + --read_ptr; + // fallthrough + case 'w': + case 'c': + case 'a': + case 'h': + case 's': + case 't': + case 'f': + case 'd': + case 'e': +#ifdef DEBUG_FAILURES + printf("*** Unsupported primary expression %.5s\n", read_ptr - 1); +#endif + return false; + case 'T': + // Invalid mangled name per + // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html +#ifdef DEBUG_FAILURES + printf("*** Invalid primary expr encoding\n"); +#endif + return false; + default: + --read_ptr; + Write('('); + if (!ParseType()) return false; + Write(')'); + if (!ParseNumber()) return false; + return Parse('E'); + } + } + + // ::= + // ::= + // ::= + + bool ParseUnresolvedType() + { + int type_start_cookie = GetStartCookie(); + switch (*read_ptr++) + { + case 'T': + if (!ParseTemplateParam()) return false; + EndSubstitution(type_start_cookie); + return true; + case 'S': + { + if (*read_ptr != 't') return ParseSubstitution(); + + ++read_ptr; + WriteStdPrefix(); + NameState type_name = {}; + if (!ParseUnqualifiedName(type_name)) return false; + EndSubstitution(type_start_cookie); + return true; + + } + case 'D': + default: +#ifdef DEBUG_FAILURES + printf("*** Unsupported unqualified type: %3s\n", read_ptr - 1); +#endif + return false; + } + } + + // ::= # unresolved name + // extension ::= # unresolved operator-function-id + // extension ::= # unresolved operator template-id + // ::= on # unresolved operator-function-id + // ::= on # unresolved operator template-id + // ::= dn # destructor or pseudo-destructor; + // # e.g. ~X or ~X + + bool ParseBaseUnresolvedName() + { +#ifdef DEBUG_FAILURES + printf("*** Base unresolved name unsupported\n"); +#endif + return false; + } + + // + // extension ::= srN [] * E + // ::= [gs] # x or (with "gs") ::x + // ::= [gs] sr + E + // # A::x, N::y, A::z; "gs" means leading "::" + // ::= sr # T::x / decltype(p)::x + // extension ::= sr + // # T::N::x /decltype(p)::N::x + // (ignored) ::= srN + E + + bool ParseUnresolvedName() + { +#ifdef DEBUG_FAILURES + printf("*** Unresolved names not supported\n"); +#endif + //TODO: grammar for all of this seems unclear... + return false; + + if (*read_ptr == 'g' && *(read_ptr + 1) == 's') + { + read_ptr += 2; + WriteNamespaceSeparator(); + } + } + + // ::= + // ::= + // ::= + // ::= cl + E # call + // ::= cv # conversion with one argument + // ::= cv _ * E # conversion with a different number of arguments + // ::= [gs] nw * _ E # new (expr-list) type + // ::= [gs] nw * _ # new (expr-list) type (init) + // ::= [gs] na * _ E # new[] (expr-list) type + // ::= [gs] na * _ # new[] (expr-list) type (init) + // ::= [gs] dl # delete expression + // ::= [gs] da # delete[] expression + // ::= pp_ # prefix ++ + // ::= mm_ # prefix -- + // ::= ti # typeid (type) + // ::= te # typeid (expression) + // ::= dc # dynamic_cast (expression) + // ::= sc # static_cast (expression) + // ::= cc # const_cast (expression) + // ::= rc # reinterpret_cast (expression) + // ::= st # sizeof (a type) + // ::= sz # sizeof (an expression) + // ::= at # alignof (a type) + // ::= az # alignof (an expression) + // ::= nx # noexcept (expression) + // ::= + // ::= + // ::= dt # expr.name + // ::= pt # expr->name + // ::= ds # expr.*expr + // ::= sZ # size of a parameter pack + // ::= sZ # size of a function parameter pack + // ::= sp # pack expansion + // ::= tw # throw expression + // ::= tr # throw with no operand (rethrow) + // ::= # f(p), N::f(p), ::f(p), + // # freestanding dependent name (e.g., T::x), + // # objectless nonstatic member reference + // ::= + + bool ParseExpression() + { + Operator expression_operator = TryParseOperator(); + switch (expression_operator.kind) + { + case OperatorKind::Unary: + Write(expression_operator.name); + Write('('); + if (!ParseExpression()) return false; + Write(')'); + return true; + case OperatorKind::Binary: + if (!ParseExpression()) return false; + Write(expression_operator.name); + return ParseExpression(); + case OperatorKind::Ternary: + if (!ParseExpression()) return false; + Write('?'); + if (!ParseExpression()) return false; + Write(':'); + return ParseExpression(); + case OperatorKind::NoMatch: + break; + case OperatorKind::Other: + default: +#ifdef DEBUG_FAILURES + printf("*** Unsupported operator: %s\n", expression_operator.name); +#endif + return false; + } + + switch (*read_ptr++) + { + case 'T': return ParseTemplateParam(); + case 'L': return ParseExpressionPrimary(); + case 's': + if (*read_ptr++ == 'r') return ParseUnresolvedName(); + --read_ptr; + // fallthrough + default: + return ParseExpressionPrimary(); + } + } + + // ::= # type or template + // ::= X E # expression + // ::= # simple expressions + // ::= J * E # argument pack + // ::= LZ E # extension + + bool ParseTemplateArg() + { + switch (*read_ptr) { + case 'J': +#ifdef DEBUG_FAILURES + printf("*** Template argument packs unsupported\n"); +#endif + return false; + case 'X': + ++read_ptr; + if (!ParseExpression()) return false; + return Parse('E'); + case 'L': + ++read_ptr; + return ParseExpressionPrimary(); + default: + return ParseType(); + } + } + + // ::= I * E + // extension, the abi says + + + bool ParseTemplateArgs(bool record_template_args = false) + { + if (record_template_args) ResetTemplateArgs(); + + bool first_arg = true; + while (*read_ptr != 'E') + { + if (first_arg) first_arg = false; + else WriteCommaSpace(); + + int template_start_cookie = GetStartCookie(); + if (!ParseTemplateArg()) return false; + if (record_template_args) EndTemplateArg(template_start_cookie); + } + ++read_ptr; + return true; + } + + // ::= N [] [] E + // ::= N [] [] E + // + // ::= + // ::= + // ::= + // ::= + // ::= # empty + // ::= + // ::= + // extension ::= L + // + // ::=